gpt4 book ai didi

ruby-on-rails - 将值数组发送到 ruby​​ 中的 sql 查询?

转载 作者:数据小太阳 更新时间:2023-10-29 07:15:13 27 4
gpt4 key购买 nike

我正在努力解决似乎是 ruby​​ 语义的问题。我正在编写一种方法,该方法从表单中获取可变数量的参数并创建一个Postgresql 查询。

def self.search(params)
counter = 0
query = ""
params.each do |key,value|
if key =~ /^field[0-9]+$/
query << "name LIKE ? OR "
counter += 1
end
end
query = query[0..-4] #remove extra OR and spacing from last

params_list = []
(1..counter).each do |i|
field = ""
field << '"%#{params[:field'
field << i.to_s
field << ']}%", '
params_list << field
end
last_item = params_list[-1]
last_item = last_item[0..-3] #remove trailing comma and spacing
params_list[-1] = last_item

if params
joins(:ingredients).where(query, params_list)
else
all
end
end

尽管 params_list 是一个数值数组,在数量上与“name LIKE ?”匹配部分查询,我收到一个错误:错误的绑定(bind)变量数(1 对 2)在:name LIKE 中? OR name LIKE ? 我尝试将 params_list 作为字符串使用,但也没有更好的效果。我对 ruby 很陌生。

我使用以下代码为 2 个参数工作,但希望允许用户提交最多 5 个(:field1、:field2、:field3 ...)

def self.search(params)
if params
joins(:ingredients).where(['name LIKE ? OR name LIKE ?',
"%#{params[:field1]}%", "%#{params[:field2]}%"]).group(:id)
else
all
end
end

有人可以阐明我真正应该如何对此进行编程吗?

最佳答案

PostgreSQL 支持标准 SQL 数组和标准 any op (...)语法:

9.23.3. ANY/SOME (array)

expression operator ANY (array expression)
expression operator SOME (array expression)

The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator, which must yield a Boolean result. The result of ANY is "true" if any true result is obtained. The result is "false" if no true result is found (including the case where the array has zero elements).

这意味着您可以像这样构建 SQL:

where name ilike any (array['%Richard%', '%Feynman%'])

这非常简洁明了,那么我们如何让 Rails 来构建它呢?这实际上很简单:

Model.where('name ilike any (array[?])', names.map { |s| "%#{s}%" })

无需手动引用,ActiveRecord 会在填充 ? 占位符时将数组转换为正确引用/转义的列表。

现在您只需构建names 数组。像这样简单的事情应该做:

fields = params.keys.select { |k| k.to_s =~ /\Afield\d+\z/ }
names = params.values_at(*fields).select(&:present)

您还可以通过折腾 split 将单个 'a b' 输入转换为 'a', 'b'展平到混合中:

names = params.values_at(*fields)
.select(&:present)
.map(&:split)
.flatten

关于ruby-on-rails - 将值数组发送到 ruby​​ 中的 sql 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22461042/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com