Ruby on rails 3 如何在rails3的where with AR查询接口中指定多个值
根据活动记录查询界面上的rails指南第2.2节:Ruby on rails 3 如何在rails3的where with AR查询接口中指定多个值,ruby-on-rails-3,activerecord,Ruby On Rails 3,Activerecord,根据活动记录查询界面上的rails指南第2.2节: 这似乎表明我可以传递一个指定条件的字符串,然后传递一个值数组,在构建arel时,这些值应该在某个点被替换。因此,我得到了一个生成条件字符串的语句,它可以是数量不等的属性,通过AND或or链接在一起,我将数组作为第二个参数传递给where方法,我得到: ActiveRecord::PreparedStatementInvalid:绑定变量的数目错误(1代表5) 这让我相信我做得不对。然而,我没有找到任何关于如何正确操作的方法。为了以另一种方式重申
这似乎表明我可以传递一个指定条件的字符串,然后传递一个值数组,在构建arel时,这些值应该在某个点被替换。因此,我得到了一个生成条件字符串的语句,它可以是数量不等的属性,通过AND或or链接在一起,我将数组作为第二个参数传递给where方法,我得到: ActiveRecord::PreparedStatementInvalid:绑定变量的数目错误(1代表5)
这让我相信我做得不对。然而,我没有找到任何关于如何正确操作的方法。为了以另一种方式重申这个问题,我需要将一个字符串传递给where方法,例如“table.attribute=?和table.attribute1=?或table.attribute1=?”,这些条件的数量未知,并且一起进行AND或OR运算,然后传递一些内容,我认为第二个参数是数组,用于替换第一个参数条件字符串中的值。这是正确的方法吗,或者,我只是在某个地方遗漏了其他一些重要的概念,而我在这个问题上完全错了?我认为无论如何,这必须是可能的,除了生成一个原始的sql字符串 听起来你在做这样的事情:
Model.where("attribute = ? OR attribute2 = ?", [value, value])
Model.where("attribute = ? OR attribute2 = ?", [value, value])
鉴于您需要这样做:
# notice the lack of an array as the last argument
Model.where("attribute = ? OR attribute2 = ?", value, value)
#notice the lack of an array as the last argument
Model.where("attribute = ? OR attribute2 = ?", value, value) Have a
请查看有关如何工作的更多详细信息。如果要将条件(属性名称和值)的开放列表链接在一起,我建议使用arel表 由于您的问题非常模糊,所以很难给出具体信息,因此我将仅针对一个简单的案例,即
Post
模型和一些属性,例如title
、summary
、和user\u id
(即,一个用户有许多帖子)解释如何做到这一点
首先,获取模型的arel表:
table = Post.arel_table
然后,开始构建谓词(最终用于创建SQL查询):
这里,table[:title]
、table[:summary]
和table[:user\u id]
是posts
表中列的表示。调用表[:title].eq(“Foo”)
时,您正在创建一个谓词,大致相当于一个查找条件(获取标题列等于“Foo”的所有行)。这些谓词可以与和和或链接在一起
当聚合谓词准备就绪时,可以使用以下命令获得结果:
Post.where(relation)
这将生成SQL:
SELECT "posts".* FROM "posts"
WHERE (("posts"."title" = "Foo" OR "posts"."summary" = "A post about foo")
AND "posts"."user_id" = 5)
这将获得标题为“Foo”或摘要为“关于Foo的帖子”且属于id为5的用户的所有帖子
请注意arel谓词可以无休止地链接在一起以创建越来越复杂的查询。这意味着,如果您有(比如)属性/值对的散列,并且知道是否要对每个属性/值对使用和或或,您可以逐个循环并建立条件:
relation = table[:title].eq("Foo")
hash.each do |attr, value|
relation = relation.and(table[attr].eq(value))
# or relation = relation.or(table[attr].eq(value)) for an OR predicate
end
Post.where(relation)
除了易于链接外,arel表的另一个优点是它们独立于数据库,因此您不必担心MySQL查询是否能在PostgreSQL中工作,等等
这是一个关于阿雷尔的更多信息:
希望有帮助。您可以使用散列而不是字符串。建立一个包含任意多个条件和相应值的散列,并将其放入where方法的第一个参数中。而不是像这样将同一参数多次传递给where()
User.where(
"first_name like ? or last_name like ? or city like ?",
"%#{search}%", "%#{search}%", "%#{search}%"
)
您可以很容易地提供散列
User.where(
"first_name like :search or last_name like :search or city like :search",
{search: "%#{search}%"}
)
这使您的查询对于长参数列表更具可读性。这实际上非常简单:
Model.where(attribute: [value1,value2])
听起来你在做这样的事情:
Model.where("attribute = ? OR attribute2 = ?", [value, value])
Model.where("attribute = ? OR attribute2 = ?", [value, value])
鉴于您需要这样做:
# notice the lack of an array as the last argument
Model.where("attribute = ? OR attribute2 = ?", value, value)
#notice the lack of an array as the last argument
Model.where("attribute = ? OR attribute2 = ?", value, value) Have a
看
有关如何工作的更多详细信息
非常接近。可以使用*my_list将数组转换为参数列表
Model.where("id = ? OR id = ?", *["1", "2"])
或
应该有效错误
出于某种原因,这就是我过去常做的事
keys = params[:search].split(',').map!(&:downcase)
# keys are now ['brooklyn', 'queens']
query = 'lower(city) LIKE ?'
if keys.size > 1
# I need something like this depending on number of keys
# 'lower(city) LIKE ? OR lower(city) LIKE ? OR lower(city) LIKE ?'
query_array = []
keys.size.times { query_array << query }
#['lower(city) LIKE ?','lower(city) LIKE ?']
query = query_array.join(' OR ')
# which gives me 'lower(city) LIKE ? OR lower(city) LIKE ?'
end
# now I can query my model
# if keys size is one then keys are just 'brooklyn',
# in this case it is 'brooklyn', 'queens'
# @posts = Post.where('lower(city) LIKE ? OR lower(city) LIKE ?','brooklyn', 'queens' )
@posts = Post.where(query, *keys )
keys=params[:search].split(',').map!(&:downcase)
#钥匙现在是['brooklyn','queens']
query=‘低层(城市)像吗?’
如果keys.size>1
#根据钥匙的数量,我需要这样的东西
#“下(城)像什么?还是更低的(城市)呢?或者更低的(城市)像?”
查询_数组=[]
键、大小、时间{query_array如果你发布了你遇到困难的代码,它将非常有用。好吧,下面发布的代码Dan与我想做的差不多,只是我不知道会有多少条件,因此也不知道有多少替换。因此,我假设我可以传递一个数组,其中包含要替换的值作为第二个参数插入。“不同数量的属性通过AND或or链接在一起”据我所知,条件要么匹配任何给定的属性,要么匹配所有属性,但不能同时匹配两者。例如attribute2=?或attribute2=?或attribute3=?
或attribute2=?和attribute2=?和attribute3=?
。是的,问题是我不知道在运行时之前会有多少这样的条件,所以我会动态更新构造第一个字符串参数。我想我可以只在字符串中插入需要匹配的值,但这肯定不太安全。似乎有一种更简单的方法来传递多个值参数,但我想不会。感谢replyI,我还没有尝试过,但您可以尝试在y上使用splat运算符我们的参数值数组:模型。其中(“attributes=?”,*array\u of_values)
如果您将其与“attributes=?”
一起使用,它将不起作用。您需要将属性名称链接在一起,以便获得一个字符串,其形式为“attribute1=?或attribute2=?”和…”
,然后代替值数组传递数组本身