Arel和多态关联加入

时间:2012-03-14 17:27:09

标签: ruby-on-rails activerecord associations arel

我有以下内容:

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加入Merchant并得到这个: ActiveRecord :: EagerLoadPolymorphicError:无法急切加载多态关联:merchant_owner

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

有什么想法吗? Arel是否支持多态关联连接?任何解决方法?我可以下载到纯SQL,但这很小便。

由于

2 个答案:

答案 0 :(得分:0)

这对Arel来说可能太过分了,我不太确定一个很好的解决方案。在您的情况下,看起来所有的merchant_owners都共享相同的经销商表,因此想要从多态关联中加入是有道理的,但通常多态关联可以与整个数据模型中的各种模型(针对不同的表)相关联。这在SQL中会变得相当丑陋,并且在一般情况下可能相当慢,这就是我期望EagerLoadPolymorphicError存在的原因。对于你的情况,可以通过以下方式解决这个问题:

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

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

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

是出于性能原因还是因为你有额外的Arel where依赖于经销商属性的子句?如果是为了性能,你可能最好回到SQL ......

答案 1 :(得分:0)

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