Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 3 如何在rails3的where with AR查询接口中指定多个值_Ruby On Rails 3_Activerecord - Fatal编程技术网

Ruby on rails 3 如何在rails3的where with AR查询接口中指定多个值

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) 这让我相信我做得不对。然而,我没有找到任何关于如何正确操作的方法。为了以另一种方式重申

根据活动记录查询界面上的rails指南第2.2节:


这似乎表明我可以传递一个指定条件的字符串,然后传递一个值数组,在构建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=?”和…”
,然后代替值数组传递数组本身