0

私は次のモデルを持っています:

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を集約する方法はありますか?

ランニングレール3.2.1

4

1 に答える 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モデルを完全に削除できます。

于 2012-10-25T20:57:36.637 に答える