重构:查找查询中的多个参数

时间:2010-10-29 18:56:30

标签: ruby-on-rails refactoring

需要一些帮助来重构这个构建查询条件的if / else块。

if params[:status] && params[:carrier]
  conditions = ["actual_delivery IS NOT NULL AND actual_delivery > scheduled_delivery AND status_id = ? AND carrier_id = ?", status.id, carrier.id]
elsif params[:status]
  conditions = ["actual_delivery IS NOT NULL AND actual_delivery > scheduled_delivery AND status_id = ?", status.id]
elsif params[:carrier]
  conditions = ["actual_delivery IS NOT NULL AND actual_delivery > scheduled_delivery AND carrier_id = ?", carrier.id]
else
  conditions = ["actual_delivery IS NOT NULL AND actual_delivery > scheduled_delivery"]
end

@packages = Package.find(:all, :conditions => conditions)

2 个答案:

答案 0 :(得分:1)

我建议在模型中创建一个范围,以处理查询的第一部分,该部分在此操作中始终相同:

class Package < ActiveRecord::Base
  named_scope :late_deliveries, :conditions => "actual_delivery IS NOT NULL AND actual_delivery > scheduled_delivery"
end

现在你可以像这样重构你的行动:

def index
  conditions = {}
  [:status, :carrer].each{|param| conditions[param] = params[param] if params[param]}

  @packages = Package.late_deliveries.find(:conditions => conditions)
end

如果:carrier和:status是此操作的唯一两个参数,那么它甚至更简单:

def index
  @packages = Package.late_deliveries.find(:conditions => params)
end

我希望这有帮助!

答案 1 :(得分:0)

你可以这样做:

conditions = "actual_delivery IS NOT NULL AND actual_delivery > scheduled_delivery"
conditions += " AND status_id = #{status.id}" if params[:status]
conditions += " AND carrier_id = #{carrier.id}" if params[:carrier]

@packages = Package.all(:conditions => [conditions])