Rails ActiveRecord:查找中的多个条件

Wil*_*son 11 ruby search activerecord ruby-on-rails hashmap

这可能比其他任何东西都更像Ruby语法.我很难在SomeObject.find上获得两个限制条件.

分开,条件似乎有效:

if search != ''
  find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
  find(:all, :conditions => ['active', 1]).shuffle
end
Run Code Online (Sandbox Code Playgroud)

第一种情况我想要的是:

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1])
Run Code Online (Sandbox Code Playgroud)

但线路抛出syntax error, unexpected ')', expecting tASSOC.

小智 17

Rails 2

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1])不是将哈希传递给方法的正确语法.如果它是方法的最后一个参数,则可以将大括号从散列中删除,但在这种情况下,您将传递一个数组作为最后一个参数.

请改用以下内容:

find(:all, :conditions => ["name LIKE ? AND active = ?", "%#{search}%", 1])
Run Code Online (Sandbox Code Playgroud)

要么

params = {:search => "%#{search}%", :active => 1}
find(:all, :conditions => ["name LIKE :search AND active = :active", params])
Run Code Online (Sandbox Code Playgroud)

Rails 3和4

您可能希望为最近的Rails版本执行更多类似的操作:

 scope :active, -> { where(active: true) }
 scope :name_like, ->(search) { where("name LIKE ?", "%#{search}%") }
Run Code Online (Sandbox Code Playgroud)

然后你会这样称呼它:

YourModel.active.name_like("Bunnies")
Run Code Online (Sandbox Code Playgroud)

这允许您在整个应用程序中以不同的组合重用这些特定查询.它还使得检索数据的代码易于阅读.

如果您不喜欢scope语法,您还可以将它们定义为类方法:

def self.active
  where(active: true)
end

def self.name_like(search)
  where("name LIKE ?", "%#{search}%")
end
Run Code Online (Sandbox Code Playgroud)

您还可以动态链接范围.这将允许您开始构建关系对象链,然后根据条件选择包含其他对象.这是应用于原始问题以获得相同结果时的样子:

results = active
results = results.name_like(search) if search.present?
Run Code Online (Sandbox Code Playgroud)