【问题标题】:Arel and polymorphic association joinsArel 和多态关联连接
【发布时间】:2012-03-31 04:58:44
【问题描述】:

我有以下几点:

class BaseReseller < ActiveRecord::Base

  set_table_name "resellers"

  acts_as_nested_set

  has_many :merchants, :as => :merchant_owner, :dependent => :destroy
end

class IPSP < BaseReseller
end    

class Agent < BaseReseller
end

class Reseller < BaseReseller
end

class Merchant < ActiveRecord::Base
  belongs_to :merchant_owner, :polymorphic => true
end

class MerchantsController < ApplicationController
  ... 
  def index
    ...
    @merchants = Merchant.joins(:merchant_owner) # breaks!
  end
end

注意我是如何尝试使用多态的 Merchant_owner 加入商家并得到这个:ActiveRecord::EagerLoadPolymorphicError: Can not eagerly load the polymorphic association :merchant_owner

@merchants = Merchant.includes(:merchant_owner) 最初可以工作,但是当我开始迭代视图中的 @merchants 数组时,它会因相同的错误而中断 - 似乎是这样,因为我们使用延迟加载的关系并且仅当调用非 Arel 方法时,它实际上会转到 DB。

有什么想法吗? Arel 是否支持多态关联连接?任何解决方法?我可以直接使用纯 SQL,但这太麻烦了。

谢谢

【问题讨论】:

    标签: ruby-on-rails activerecord associations arel


    【解决方案1】:

    这对 Arel 的要求可能太多了,我不确定是否有很好的解决方案。在您的情况下,看起来所有的 Mercer_owners 共享同一个经销商表,因此希望从多态关联加入是有道理的,但通常多态关联可以与整个数据模型中的各种模型(针对不同的表)相关.这在 SQL 中会变得非常丑陋,并且在一般情况下可能会非常慢,这就是我期望 EagerLoadPolymorphicError 存在的原因。对于您的情况,使用以下方法可能是有意义的:

    Merchant.joins("INNER JOIN resellers on merchant_owner_id = resellers.id")
    

    当然,将此连接作为模型上的范围是最干净的,因此您可以只执行 Merchant.joined_with_owners 并将 SQL 降级到模型层。但是,如果其他非经销商模型有许多商家,这将不起作用。

    我有点惊讶您在 Merchant.includes(:merchant_owner) 中看到相同的错误,即使我访问各种属性,我也没有看到类似的数据,但这可能是由于各种差异。

    出于性能原因或因为您有其他依赖于经销商属性的 Arel where 子句而尝试预先加载?如果是为了性能,最好还是使用 SQL...

    【讨论】:

    • 事实上,您可能希望通过在 ('Agent', 'Reseller', 'IPSP') 中添加“and Mercer_owner_type”来保护该连接
    【解决方案2】:

    问题是其中一个表中缺少一列。 Rails 确实非常好地支持 STI 层次结构之间的多态关联,但要注意多态、STI 等的正确列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多