2012-03-14 31 views
3

我有以下幾點:阿雷爾和多態的關聯連接

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:不能急於加載多態性關聯:merchant_owner。 @merchants = Merchant.includes(:merchant_owner)最初起作用,但是當我開始遍歷視圖中的@merchants數組時,它打破了同樣的錯誤 - 似乎是這樣,因爲我們使用延遲加載的關係和只有當非Arel方法被調用時,它纔會到達DB。

任何想法? Arel是否支持多態關聯連接?任何解決方法?我可以下降到純粹的SQL,但這是小豬。

感謝

回答

0

問題是其中一個表中缺少一列。 Rails支持STI層次結構之間的多態關聯非常好,但要注意關於多態性,STI等的正確列。

0

這可能是過分的要求阿雷爾的,我不知道一個很好的解決方案的。在你的情況下,它看起來像所有的merchant_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 ...

+1

實際上,您可能希望通過在('Agent')中添加「and merchant_owner_type來保護該連接」 ,'經銷商','IPSP')「 – njorden 2012-06-18 21:09:24