I have the following models:
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
Is there a clever way for me to get ALL Subscriptions that a User has.
I tried
u = User.first
subs = u.all_subscriptions
but that is erroring out (undefined method subscriptions' for #<ActiveRecord::Relation:). I think it’s choking when I try to use the has_many :subscriptions on the HighSchoolSubscription because a user has_many :high_school_subscriptions. (This line: self.high_school_subscriptions.subscriptions).
Is there a way to aggregate has_many on a has_many in Rails?
Running rails 3.2.1
self.subscriptionsdoes not return anArraybutActiveRecord::Relation. That’s the reason why the+methods and does not work and your get the mentioned error. The simplest fix is to do it this way:The
allmethod will trigger the database queries and return an array. Because a user might have many high school subscriptions and these also may has many subscriptions, you have to iterate over all high school subscriptions and collect their subscriptions. As you can see, this is a complete overkill.Redesign your data model or just do it a different way.
Perhaps, scoping the
Subscriptionmodel might be the way. Add it an attribute that would specify what kind of subscription it is and then you can completely remove theHighSchoolSubscriptionmodel.