2012-10-25 12 views
0

我有以下型號:骨料的has_many與其他的has_many的Rails

class User < ActiveRecord::Base 
    has_many :subscriptions, as: :subscribable 
    has_many :user_to_high_school_subscriptions 
    has_many :high_school_subscriptions, through: :user_to_high_school_subscriptions 

    def all_subscriptions 
    self.subscriptions + self.high_school_subscriptions.subscriptions 
    end 
end 

class UserToHighSchoolSubscription < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :high_school_subscription 
end 

class HighSchoolSubscription < ActiveRecord::Base 
    has_many :user_to_high_school_subscriptions 
    has_many :users, through: :user_to_high_school_subscriptions 
    has_many :subscriptions, as: :subscribable 
end 

class Subscription < ActiveRecord::Base 
    belongs_to :subscribable, polymorphic: true 
end 

有我讓所有Subscription s表示一個User有一個聰明的辦法。

我試圖

u = User.first 
subs = u.all_subscriptions 

但被示數出(undefined method subscriptions' for #<ActiveRecord::Relation:)。當我嘗試使用HighSchoolSubscription上的has_many :subscriptions時,我認爲這是窒息,因爲userhas_many :high_school_subscriptions。 (此行:self.high_school_subscriptions.subscriptions)。

有沒有辦法在Rails中has_many上聚合has_many?

運行軌道3.2.1

回答

1

self.subscriptions沒有返回ArrayActiveRecord::Relation。這就是爲什麼+方法不起作用的原因,並且你得到了提到的錯誤。最簡單的解決方法是這樣來做:

def all_subscriptions 
    self.subscriptions.all + self.high_school_subscriptions.all.collect { |hss| hss.subscriptions.all }.flatten 
end 

all方法將觸發數據庫查詢並返回一個數組。由於用戶可能有許多高中訂閱,而且這些訂閱也可能有很多訂閱,因此您必須遍歷所有高中訂閱並收取訂閱。正如你所看到的,這是一個完整的矯枉過正。

重新設計您的數據模型,或者以不同的方式做。

也許,範圍Subscription模型可能是這樣的。添加一個屬性,指定它是什麼類型的訂閱,然後您可以完全刪除HighSchoolSubscription模型。

+0

'flatten'方法非常有用。謝謝 –