ruby ActiveRecord Where子句在OR运算符中使用数组项

hs1ihplo  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(110)

我有一个这样的数组

arr = %w[android ios]

我想在Where子句中使用这些值,如下所示:

SELECT * FROM controls
WHERE company_id = '12345' AND (ios > 13 OR android > 14)

其中,()中的字段是数组的值。如果数组中只有一个值,

WHERE company_id = '12345' AND (ios > 13)

例如
可以使用Ruby on Rails ActiveRecord吗?

acruukt9

acruukt91#

看起来你不需要数组,而是像这样的散列

more_than = {
  ios: 13,
  android: 14
}

您可以从带有占位符的数组中构建带有sanitize_sql_for_conditions的SQL条件字符串

sql_condition_array =
  more_than.each_with_object([]) do |(atr, value), sql_array|
    if sql_array.empty?
      sql_array[0] = "#{atr} > ?"
    else
      sql_array[0] << " OR #{atr} > ?"
    end

    sql_array << value
  end
# => ["ios > ? OR android > ?", 13, 14]

sql_condition = Control.sanitize_sql_for_conditions(sql_condition_array)
# => "ios > 13 OR android > 14"

或者可以直接

sql_condition = more_than.map { |atr, value| "#{atr} > #{value}" }.join(" OR ")
# => "ios > 13 OR android > 14"

然后

Control.where(company_id: 12345).where(sql_condition)

查询将是这样的:

SELECT "controls".* FROM "controls"
WHERE "controls"."company_id" = 12345
AND (ios > 13 OR android > 14);

如果该哈希值只包含一个元素,则不会像这样使用OR

SELECT "controls".* FROM "controls"
WHERE "controls"."company_id" = 12345
AND (ios > 13);
velaa5lx

velaa5lx2#

定义一个hash而不是数组hash = { 'android' => 14, 'ios' => 13}
然后形成一个可以传递给where的字符串
完整的代码如下所示

hash = { 'android' => 14, 'ios' => 13}
str = ''
hash.each do |k, v|
    str += k + ' > ' + v.to_s + ' OR '
end
Control.where(company_id: '12345').where(str[0..-5])
qacovj5a

qacovj5a3#

一个更ActiveRecord的方法:

Control.where(company_id: 12345).where("ios > ?", 13).or(Control.where(company_id: 12345).where("android > ?", 14))

更好的方法:

controls = Control.where(company_id: 12345)
controls = controls.where("ios > ?", 13).or(controls.where("android > ?", 14))

这将生成下一个SQL查询:

SELECT "controls".* FROM "controls" WHERE "controls"."company_id" = 12345 AND (ios > 13 OR android > 14)

相关问题