【问题标题】:How to use scopes to filter data by partial variable如何使用范围按部分变量过滤数据
【发布时间】:2020-01-22 14:23:13
【问题描述】:

我有一些工作脚本使用 Active Record 作用域过滤我的结果。当我想通过将参数与数据库中的数据进行比较来过滤时,一切正常。

但我在 _car.html.erb 部分中有一些计算汽车价格的函数,这个函数的结果取决于参数结果。

我如何通过此函数的结果来确定搜索结果的范围,并仅显示低于某个价格(在参数中定义)的汽车。

一些代码使其更清晰:

car.rb(模型文件)

  scope :price_leasing, -> (price_leasing) { where('price_leasing <= ?', price_leasing) }
  # for now price_leasing is getting price from database
  scope :brand, -> (brand) { where brand: brand }
  scope :car_model, -> (car_model) { where car_model: car_model }
  scope :category, -> (category) { where category: category }

cars_controller.rb(控制器文件)

def index
  @cars = Car.where(nil)
  @cars = @cars.price_leasing(params[:price_leasing]) if params[:price_leasing].present?
  @cars = @cars.brand(params[:brand]) if params[:brand].present?
  @cars = @cars.car_model(params[:car_model]) if params[:car_model].present?
  @cars = @cars.category(params[:category]) if params[:category].present?

  @brands = Brand.all # importing all car brands into filters
end 

在 index.html.erb 我有“渲染@cars”代码

<%= 
  if @cars.size > 0
    render @cars.where(:offer_status => 1)
  else
    render html: '<p>Nie znaleziono  pasujących wyników.</p>'.html_safe
  end
 %>

在 _car.html.erb 文件中我有来自助手的功能

<h3 class="car-cell__price"><%= calculate_car_price(car.price, car.id) %> <span class="car-cell__light-text">zł/mc</span></h3>

我在 helper 中的 calculate_car_price() 函数

def calculate_car_price(car_price, car_id)
  car = Car.find(car_id)
  fullprice = car_price

  if params[:price_leasing].present?
    owncontribution = params[:price_leasing].to_i
  else
    owncontribution = car.owncontribution
  end 
  pv = fullprice - owncontribution + (0.02 * fullprice)

  if params[:period].present?
    carperiod = params[:period].to_i
    carprice = (Exonio.pmt(0.0522/60, carperiod, pv)) * -1
  else
    carprice = (Exonio.pmt(0.0522/60, 60, pv)) * -1
  end
  p number_with_precision(carprice, precision: 0)
end

我很想通过这个函数的结果来确定范围。是否可以?

【问题讨论】:

  • 我不确定我是否理解这个问题,但这就是我从你的问题中得到的。您提供了"price_leasing" 查询参数,但calculate_car_price 仍显示高于提供的"price_leasing" 查询参数的价格。我是否正确地从你的问题中暗示了这一点?如果是这样,您是否可以将calculate_car_price 的逻辑添加到问题中,因为必须将相同的逻辑应用于查询/范围才能获得匹配的结果。
  • @3limin4t0r 我刚刚在主帖中添加了该方法,但你理解错了。我的数据库中有“price_leasing”字段,现在我正在将搜索引擎中的 params[:price_leasing] 与数据库“price_leasing”字段进行比较。我想要实现的是将搜索引擎中的“price_leasing”参数与“calculate_car_price”方法结果进行比较。清楚吗?对不起,如果没有

标签: ruby ruby-on-rails-6


【解决方案1】:

关于范围的事情是它们是在数据库级别实现的。您要选择具有值的记录

要在数据库级别执行您想要的操作,您需要在数据库中创建一个虚拟列,实现将根据您使用的数据库产品而改变(我不希望 postgreSQL 中的虚拟列定义是与 mySQL 中的虚拟列定义相同)

所以我不确定是否有最佳方式来做到这一点。

我建议您在模型Car 中构建自己的类方法和实例方法。它的性能会降低,但更容易理解和实施。

def self.car_price_under(target_price, params)
  select { |v| v.car_price_under?(target_price, params) }
end


def car_price_under?(target_price, params)
  full_price = price
  if params[:price_leasing].present?
     my_own_contribution = params[:price_leasing].to_i
   else
    my_own_contribution = owncontribution
  end 
  pv = full_price - my_own_contribution + (0.02 * full_price)
  if params[:period].present?
    car_period = params[:period].to_i
    new_car_price = (Exonio.pmt(0.0522/60, car_period, pv)) * -1
  else
    new_car_price = (Exonio.pmt(0.0522/60, 60, pv)) * -1
  end
  new_car_price <= target_price
end

这会让你...

 @cars = Car.where(nil)
 @cars = @cars.brand(params[:brand]) if params[:brand].present?
 @cars = @cars.car_model(params[:car_model]) if params[:car_model].present?
 @cars = @cars.category(params[:category]) if params[:category].present?
 @cars = @cars.car_price_under(target_price, params) if target_price.present?

请注意,这是在 Rails 中发生的,而不是在数据库中,因此应在所有其他范围之后调用 car_price_under 方法,以尽量减少需要检查的记录数。您不能链接其他范围,因为 @cars 将是一个数组...如果您希望能够链接其他范围(或者您想要一个活动记录关系,而不是数组),您可以执行类似 @cars = Car.where(id: @cars.pluck(:id)) 的操作

【讨论】:

  • 你好史蒂夫,谢谢你的回答,它非常复杂,给我指明了方向:) 我有一些语法问题(链接到选择行):/Applications/XAMPP/xamppfiles/htdocs/ git/alertbudget/app/models/car.rb:3:语法错误,意外 '}',期待 '=' ...ce_under?{target_price, params} } ... ^ /Applications/XAMPP/xamppfiles/htdocs/ git/alertbudget/app/models/car.rb:14:语法错误,意外结束,期待'}'
  • 嗨,对不起,第 3 行应该是 select { |v| v.car_price_under?(target_price, params) } 我使用括号而不是括号。第 14 行错误我不确定...你能在你的问题中发布你的 car.rb 的第 1 行到第 14 行吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 2018-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-17
  • 2016-12-23
相关资源
最近更新 更多