Rails 2.3.5
我已经查看了一些与动态建立条件有关的ActiveRecord查找的其他问题。
我知道有很多很棒的宝石,比如搜索逻辑,这在Rails3中更好。但是,我正在使用geokit进行地理搜索,我正在尝试构建一个标准条件集,这将允许我组合一系列不同的过滤器。
我有12个不同的过滤器,我正在尝试动态组合以进行高级搜索。我需要能够在(?)和IS NULL条件中混合使用等于,大于,小于等等。
以下是我正在努力工作的一个例子:
conditions = []
conditions << ["sites.site_type in (?)", params[:site_categories]] if params[:site_categories]
conditions << [<< ["sites.operational_status = ?", 'operational'] if params[:oponly] == 1
condition_set = [conditions.map{|c| c[0] }.join(" AND "), *conditions.map{|c| c[1..-1] }.flatten]
@sites = Site.find :all,
:origin => [lat,lng],
:units => distance_unit,
:limit => limit,
:within => range,
:include => [:chargers, :site_reports, :networks],
:conditions => condition_set,
:order => 'distance asc'
当条件表达式只有单个变量时,我似乎能够正常工作但是当我有一个(?)并且有一个值数组时,我得到一个错误的数字错误束缚条件。我加入和平整条件的方式(根据Combine arrays of conditions in Rails的答案)似乎没有正确处理数组,我不理解扁平化逻辑足以追踪问题。
所以,假设我在params中有3个值[:site_categories]我将上面的代码留给我以下内容:
条件是
[["sites.operational_status = ?", "operational"], ["sites.site_type in (?)", ["shopping", "food", "lodging"]]]
扁平的尝试是:
["sites.operational_status = ? AND sites.site_type in (?)", ["operational"], [["shopping", "food", "lodging"]]]
这给了我:
错误的绑定变量数(4为2)
我要退后一步,将所有这些转换为命名范围,但我真的很想了解如何以这种方式工作。
答案 0 :(得分:3)
Rails 4
users = User.all
users = User.where(id: params[id]) if params[id].present?
users = User.where(state: states) if states.present?
users.each do |u|
puts u.name
end
旧答案
Monkey补充Array类。在monkey_patch.rb
目录中创建名为config/initializers
的文件。
class Array
def where(*args)
sql = args.first
unless (sql.is_a?(String) and sql.present?)
return self
end
self[0] = self.first.present? ? " #{self.first} AND #{sql} " : sql
self.concat(args[1..-1])
end
end
现在你可以这样做:
cond = []
cond.where("id = ?", params[id]) if params[id].present?
cond.where("state IN (?)", states) unless states.empty?
User.all(:conditions => cond)