【问题标题】:ActiveRecord Use An array of arrays As ParametersActiveRecord 使用数组数组作为参数
【发布时间】:2013-10-10 15:22:11
【问题描述】:

我想形成以下查询:

SELECT tracked_points.* 
FROM tracked_points 
WHERE
(id = 87 AND zone_id = 457)
OR
(id = 88 AND zone_id = 457)

我对该函数的输入将是[id, zone_id] 的嵌套数组,类似于:

[[87, 457], [88, 457]]

我尝试了一个我在squeel gem 网站上看到的小技巧

arr = [[87, 457], [88, 457]]
TrackedPoint.where((["(id = ? AND zone_id = ?)"] * arr.size).join(" OR "), *arr)

但它不喜欢将嵌套数组作为参数。

我想出的解决方案只是编译一个 SQL 字符串,但不使用准备好的语句的任何参数清理:

matches = arr.map do |i|
  "(id = #{i[0]} AND zone_id = #{i[1]})"

TrackedPoint.where(matches.join(" OR ")

我觉得 squeel 可以提供答案,但如果有纯 ActiveRecord 答案,我也愿意尝试一下。

  • Rails 3.2.13
  • 红宝石 1.9.3-p392

【问题讨论】:

  • ActiveRecord 仅限于创建复杂的查询。如果没有像 squeel 这样的外部附加组件,我认为你不会比生成这个字符串做得更好。即使您会在 SQL 中找到一些有趣的更好的方法,您仍然会生成后续字符串。
  • @EdgarsJekabsons 知道如何在这种方法中添加参数清理吗?
  • 查看这个方法:api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/… 我认为它应该在连接对象上可用,所以你应该能够像这样访问它:TrackedPoint.connection.quote
  • @EdgarsJekabsons 我找不到任何有关如何使用quote 的语法示例。你知道它是怎么用的吗?

标签: sql ruby-on-rails activerecord squeel


【解决方案1】:

你必须先flatten嵌套数组。

TrackedPoint.where((["(id = ? AND zone_id = ?)"] * arr.size).join(" OR "), *(arr.flatten))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 2019-12-02
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多