有条件地链接Rails ActiveRecord查询中的子句

时间:2014-04-30 21:55:06

标签: ruby-on-rails ruby rails-activerecord

我有一个表单,当填充时必须触发一个特定的查询,这取决于表单有哪些参数,所以我在我的模型中有一个方法,我相信应该是这样的:

def form_query(params)

  query = ''
  if params.has_key?('size')
    query = query.where(size: params['size'])
  end

  if params.has_key?('title')
    query = query.where(title: params['title'])
  end

  # More conditionals depending on params.
end

我的问题是,query在开始时必须做什么?我把query = '',但我想知道什么是基本情况,所以我可以有条件地添加更多'其中'条款。

3 个答案:

答案 0 :(得分:6)

查询不是字符串;他们查询对象。所以你想要像

这样的东西
query = YourModel.scoped # Rails 3; in Rails 4, use .all
if params.has_key?('size')
  query = query.where(size: params['size'])
end

答案 1 :(得分:2)

或者,您可以按以下方式更新代码:

  def self.form_query(params)
    options = {}
    fields = ["body", "title"].freeze  ## Add other options
    if params.present?
      fields.each do |field|
        options[field] = params[field] if params[field]
      end
    end
    if options.present?
      where(options) 
    else
       all  ## or nil if you don't want to show any records in view
    end
  end 

此外,form_query应该是模型中的类方法。 在要查询的fields数组中添加更多选项。 它不仅使您的代码紧凑,而且还可以进行单个数据库调用。

答案 2 :(得分:0)

这是 Kirti Thorat 版本的更精简版本:

FIELDS = ["size", "title"].freeze  ## Add other options

def self.form_query(params)
  return all unless params.present?

  options = params.select { |k, _v| FIELDS.include? k.to_s }
  options.present? ? where(options) : all
end 

我已经完成了 k.to_s 以便您可以将 params 键作为字符串或符号传递。

如果你想在没有传递参数的情况下返回 nil 你可以这样做:

FIELDS = ["size", "title"].freeze  ## Add other options

def self.form_query(params)
  return unless params.present?

  options = params.select { |k, _v| FIELDS.include? k.to_s }
  where(options) if options.present? 
end