ActiveRecord是否支持sql语句中的动态条件?

时间:2009-06-09 13:22:47

标签: sql ruby-on-rails search activerecord conditional-statements

我想在Rails应用程序中进行SQL查询,该应用程序在添加下拉菜单时添加条件。显然,如果未选择下拉列表,我不想使用空白条件进行搜索。如何在SQL语句中开发动态条件?

未经测试的例子:

未选择下拉列表时:Object.find(“billy,”:conditions => {})

选择下拉列表时:Object.find(“billy,”:conditions => {“last_name =>”johnson“})

感谢您的投入!

4 个答案:

答案 0 :(得分:5)

不太确定您在做什么,但实现此目的的一般方法是将下拉值(不可见文本)作为您要选择的对象的ID。如果您没有选择,那么您可以使用以下内容:

last_name = unless params[:object][:last_name]

conditions = []
conditions << "last_name = ?" unless last_name.blank?
conditions << last_name unless last_name.blank?

Object.find("billy", :conditions => conditions)

查看this link以了解有关ActiveRecord::Base.find()方法的更多信息以及使用它们的正确方法。另请查看this great guide以了解如何保护自己免受SQL注入攻击。

编辑1:修改后的代码更清晰。这种方法还具有能够轻松添加单独条件的优点,只需确保添加所有“something =?”在添加关联值(param)之前。

编辑2:如果您还没有看到select form helper,可以考虑将其用于下拉列表。让生活更轻松: - )

答案 1 :(得分:3)

假设你的#find在一个控制器中并且所选的值是作为params中的项目进入的(我认为你应该考虑改变一些事情!)那么你应该可以做类似的事情这样:

if params[:last_name] # or whatever it's actually called
  Object.find("billy," :conditions => {'last_name = ?', params[:last_name]})
else
  Object.find("billy")
end

如果你正在使用一个合理的最新版本的ActiveRecord(2.1应该这样做,可能是2.0),那么你可以将该逻辑降低到named_scope

class Object < ActiveRecord::Base
  named_scope :for_last_name, lambda { |nm| { :conditions => nm.nil? ? {} : { last_name => nm } }

然后你的控制器归结为(我们喜欢瘦控制器)

Object.for_last_name(params[:last_name])

(有点未经测试)

答案 2 :(得分:1)

也许这个?

Object.find("billy", :conditions => last_name.nil? ? {} : {:last_name => last_name})

答案 3 :(得分:0)