我有以下内容:
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,但这很小便。
由于
答案 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等的正确列。