【问题标题】:Avoid Binding Variables in Rails #where避免在 Rails #where 中绑定变量
【发布时间】:2021-12-12 14:04:15
【问题描述】:

如果我有一个多态关联,比如:

create Transmission < ApplicationRecord
  belongs_to :transmittable, polymorphic: true
end

create Contact < ApplicationRecord
  has_many :transmissions, as: :transmittable
end

create Product < ApplicationRecord
  has_many :transmissions, as: :transmittable
end

...那么下面使用transmittable_type的绑定变量...

Transmission.where(transmittable_type: 'Product')

当产品和联系人的传输数量之间存在较大偏差时,这可能是不可取的,因为缺少与 Oracle 的绑定变量窥视等效的方法可能会导致对结果基数的错误估计。

问题:在这种情况下有没有办法避免使用绑定变量,除了:

Transmission.where("transmittable_type = 'Product'")

...我不喜欢,因为需要在复杂的查询中识别 transmissions 的正确表别名?

我已将 plan_cache_mode 视为解决此问题的数据库解决方法,但它似乎没有提供解决方案。

【问题讨论】:

    标签: ruby-on-rails postgresql


    【解决方案1】:

    ActiveRecord 查询接口将所有内容参数化为一种安全的默认方法以避免 SQL 注入,并且在传递哈希时确实没有办法避免它(至少据我所知)。不过,您可以使用 Arel 来构造查询:

    class Transmission < ApplicationRecord
      def self.by_transmittable_type(type)
        where(arel_table[:transmittable_type].eq(type))
      end
    end
    

    Arel 将简单地清理传递给 .eq 的值并将其用作 SQL 字符串的一部分。

    【讨论】:

    • 谢谢 - 这确实是不需要清理的情况,因为参数是代码库的一部分。其中大部分实际上将在作用域中实现。我想我在这里真正要寻找的是传递给where 的参数,上面写着“不要绑定这些查询参数”,但我不认为这样的事情存在。
    • 清理实际上只是转义引号,从性能的角度来看这是完全可以忽略的。
    猜你喜欢
    • 1970-01-01
    • 2011-09-07
    • 2017-10-11
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2018-06-08
    相关资源
    最近更新 更多