按实例方法计算的值进行过滤

时间:2014-06-26 00:48:51

标签: ruby-on-rails ruby

我的House模型具有price属性,该属性是使用实例方法计算的。

让我们说价格因市场利率,通货膨胀等而不断变化。因此,我们需要一种price_today方法来获得当前价格。

如何使用最高价格和最低价格创建命名范围(或其他内容)来过滤房屋?

我尝试过做这样的事情,但我觉得这有点像个hacky ......

  def index
    @houses = # get houses from DB

    if not params[:max_price].nil?
      @houses.keep_if { |h|  h.price_today <= params[:max_price].to_f }
    end

    if not params[:min_price].nil?
      @houses.keep_if { |h| h.price_today >= params[:min_price].to_f }
    end
  end

2 个答案:

答案 0 :(得分:1)

命名范围(或where子句)查询和过滤实例化对象肯定会更快。
但是,我担心如果数据库中不存在price_today,您将无法使用它们。

但是,您可以改进代码 条件可以更简单,您只需拨打一次keep_if

即可
max = params[:max_price].presence
min = params[:min_price].presence

if max || min
  @houses.keep_if do |house|
    a = max ? (house.price_today <= max.to_f) : true
    b = min ? (house.price_today >= min.to_f) : true
    a && b
  end
end

如果您愿意,可以使用select而不是keep_if

答案 1 :(得分:0)

另一种变化:

{ max_price: ->(price, max) { price <= max },
  min_price: ->(price, min) { price >= min } }.each { |prop, cond|
    @houses.select! { |h| cond.(h.price_today, params[prop].to_f) } unless params[prop].nil?
}

对于特殊属性的lambda,您可以轻松添加另一个条件=)