我有以下型号:
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
所有的User
。
我试过
u = User.first
subs = u.all_subscriptions
但这是错误的(undefined method subscriptions' for #<ActiveRecord::Relation:
)。当我尝试使用has_many :subscriptions
HighSchoolSubscription
因为user
has_many :high_school_subscriptions
时,我认为这很令人窒息。 (这一行:self.high_school_subscriptions.subscriptions
)。
有没有办法在Rails中的has_many上聚合has_many?
运行rails 3.2.1
答案 0 :(得分:1)
self.subscriptions
不会返回Array
,而是ActiveRecord::Relation
。这就是为什么+
方法不起作用并且你得到上述错误的原因。最简单的解决方法是这样做:
def all_subscriptions
self.subscriptions.all + self.high_school_subscriptions.all.collect { |hss| hss.subscriptions.all }.flatten
end
all
方法将触发数据库查询并返回一个数组。因为用户可能有许多高中订阅,并且这些订阅也可能有许多订阅,所以您必须遍历所有高中订阅并收集他们的订阅。如你所见,这是一个彻头彻尾的过度杀伤。
重新设计您的数据模型,或者只是采用不同的方式。
或许,确定Subscription
模型的范围可能就是这样。添加一个属性,指定它的订阅类型,然后您可以完全删除HighSchoolSubscription
模型。