执行查询的常用方法是链接方法,例如:
Post.where(active: true).select(:id, :title).limit(5)
有没有一种方法可以使用哈希来构造此查询?即:
Post.where(
where: [{active: true}],
select: [:id, :title],
limit: 5
)
(各种原因,例如可以响应用户查询来构造哈希,然后将其序列化以供以后处理。)
答案 0 :(得分:1)
简短的回答是“否”。
但是
ransack和rack-reducer之类的宝石可以帮助您做到这一点
OR
您总是可以自己做。
定义一种方法来获取我们感兴趣的参数:
def query_params
params.slice(:where, :select, :limit) # or make a proper permit call
end
为此用户定义基本范围:
def base_scope
Post.where(whateveryouwant)
end
然后,您需要遍历这些并将它们应用于我们的ActiveRecord::Relation
:
query_params.reduce(base_scope) { |ac, (key, value)| ac.public_send(key, value) }
答案 1 :(得分:1)
您可以在模型上定义自定义类方法,以将查询参数作为大哈希值传递,然后使用inject准备链接的查询。 (如果适用,您也可以使用each_with_object)。
class Post
def self.criteria(options = {})
options.inject(self) do |out, (k, v)|
out = out.send(k, v)
out
end
end
end
hash = {
where: { active: true },
select: [:id, :title],
limit: 5
}
Post.criteria(hash)
=> # ActiveRecord Relation for above query
如果您的where
键具有如问题中所述的哈希数组作为值,则可以将其转换为单个哈希,如下所示:
Post.where(foo: 1).where(bar: 2)
与:
Post.where(foo: 1, bar: 2)
执行以下转换:
hash[:where] = hash[:where].each_with_object({}) { |h, out| out.merge!(h) }