如何在 ActiveRecord 准备语句中使 ruby​​ 数组成为 x、y、z

Posted

技术标签:

【中文标题】如何在 ActiveRecord 准备语句中使 ruby​​ 数组成为 x、y、z【英文标题】:how to make a ruby array be a x,y,z in an ActiveRecord prepared statement 【发布时间】:2015-07-03 22:27:44 【问题描述】:

我在 heroku 上使用 Ruby on Rails 3.20 和 Postgres 9.4 并且有以下片段:

metro_area_ids=[3,4,7]
a=metro_area_ids.join(',')
self.where("metro_area_ids ilike '%-?-%' or metro_area_ids ilike '%-?-%' or metro_area_ids='%-?-%'", a)  # how to make this array be 3,4,7 joining doesn't work

我希望能够传递一个从 1 到 10 的值数组(作为任意上限),并能够使用 postgres ilike 语句查询我们的表。

但我明白了

ActiveRecord::PreparedStatementInvalid:绑定变量的数量错误 (1 for 2) in: metro_area_ids ilike '%-?-%' or metro_area_ids ilike '%-?-%'

如何让这个数组中的任意数量的输入工作?

编辑

所以这行不通

Queryable.where("metro_area_ids ilike '%-?-%' or metro_area_ids ilike '%-?-%'",[1,13])

所以这确实有效,这就是我想要模拟的:

Queryable.where("metro_area_ids ilike '%-?-%' or metro_area_ids ilike '%-?-%'",1,13)

【问题讨论】:

第一个和第二个条件在我看来是一样的。预期的输出是什么? 你使用什么数据库?我认为LIKE 是不可能的,但REGEXP 可能是可能的。 ILKE => Postgres,对吧? 绝对可能 - 我使用 Postgres 9.4 并将更新问题。 如果您只需要减少错误,请删除.join(',') 这样查询应该可以工作。但它不会正常工作,例如如果id 将是字段中的最后一个元素 谢谢@itsnikolay - 但据我所知,它没有。我在上面的编辑中添加了我尝试过的内容 【参考方案1】:

这是因为您通过 ? 引用了许多参数,同时只指定一个(字符串)、使用命名占位符或单独指定数组的每个元素。

使用命名占位符

metro_area_ids= st: 3, nd: 4, th: 7 
self.where("metro_area_ids ilike '%-:st-%' or metro_area_ids ilike '%-:nd-%' or metro_area_ids='%-:th-%'", metro_area_ids) 

分别提供每个元素

self.where("metro_area_ids ilike '%-?-%' or metro_area_ids ilike '%-?-%' or metro_area_ids='%-?-%'", metro_area_ids[0], metro_area_ids[1], metro_area_ids[2]) 

【讨论】:

ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (1 for 3) in: 将其视为一个参数【参考方案2】:

您可以简单地通过$ ruby test.rb 测试它并将以下内容复制到文件中

require 'active_record'

class Metro < ActiveRecord::Base
  establish_connection adapter: 'sqlite3', database: 'foobar.db'
  connection.create_table table_name, force: true do |t|
    t.string :metro_area_ids
  end
end

Metro.create!([
   metro_area_ids: '1,2,3,4' ,
   metro_area_ids: '2,3,4,5' ,
   metro_area_ids: '3,4,5,6' ,
])
metros = Metro.where("metro_area_ids LIKE ?", "%2,3%")
p metros.inspect
#=> [#<Metro id: 1, metro_area_ids: \"1,2,3,4\">,
     #<Metro id: 2, metro_area_ids: \"2,3,4,5\">]

【讨论】:

有点不同的想法。不处理不连续的【参考方案3】:

这样怎么样:

Queryable.where("metro_area_ids ilike '?' or metro_area_ids ilike '?'", "%-#1-%", "%-#13-%")

【讨论】:

以上是关于如何在 ActiveRecord 准备语句中使 ruby​​ 数组成为 x、y、z的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle 中使 Select 语句更快

如何在 R 中使 naiveBayes() 的公式参数通用?

如何在我的助手而不是视图中循环访问 ActiveRecord_Relation?

如何在发布版本中使标签不可见[关闭]

Rails Activerecord 关系:使用子查询作为 SQL 选择语句的表

如何在 oracle 中使可空列不为空