質問

RubyとRailsの両方に新しいですが、私は今までに教育を受けた本です(明らかに何も意味がありません、笑)。

EventEventとUserという2つのモデルがあり、EventUserテーブルを介して参加しています

class User < ActiveRecord::Base
  has_many :event_users
  has_many :events, :through => :event_users
end

class EventUser < ActiveRecord::Base
  belongs_to :event
  belongs_to :user

  #For clarity's sake, EventUser also has a boolean column "active", among others
end

class Event < ActiveRecord::Base
  has_many :event_users
  has_many :users, :through => :event_users
end

このプロジェクトはカレンダーです。このカレンダーでは、特定のイベントにサインアップして名前を消している人を追跡する必要があります。多対多は良いアプローチだと思いますが、このようなことはできません:

u = User.find :first
active_events = u.events.find_by_active(true)

イベントには実際には余分なデータがないため、EventUserモデルにはあります。そして、私ができる間:

u = User.find :first
active_events = []
u.event_users.find_by_active(true).do |eu|
  active_events << eu.event
end

これは「レールウェイ」に反しているようです。誰も私を啓発できますか、これは今夜(今朝)長い間私を悩ませてきましたか?

役に立ちましたか?

解決

このようなものをユーザーモデルに追加してはどうですか?

has_many  :active_events, :through => :event_users, 
          :class_name => "Event", 
          :source => :event, 
          :conditions => ['event_users.active = ?',true]

その後、次の呼び出しを行うだけで、ユーザーのアクティブなイベントを取得できます。

User.first.active_events

他のヒント

Milan Novotaには良い解決策があります&#8211;しかし、:conditions は非推奨になり、:conditions =&gt; ['event_users.active =?'、true] ビットは、とにかくあまりレールに見えません。私はこのようなものを好む:

has_many :event_users
has_many :active_event_users, -> { where active: true }, class_name: 'EventUser'
has_many :active_events, :through => :active_event_users, class_name: 'Event', :source => :event

その後、次のように呼び出すだけで、ユーザーのアクティブなイベントを取得できます。

User.first.active_events

u.eventsはuser_eventsテーブルを explicitly 呼び出していませんが、必要な結合のために、そのテーブルはまだ暗黙的に SQLに含まれています。そのため、検索条件でそのテーブルを引き続き使用できます。

u.events.find(:all, :conditions => ["user_events.active = ?", true])

もちろん、このルックアップを何度も行う予定の場合は、Milan Novotaが提案するように別の関連付けを指定してください。しかし、そのようにするための要件はありません

>

まあ、実際に必要なよりも User モデルに多くの責任が置かれています。そうする正当な理由はありません。

実際には、次のように、 EventUser モデルでスコープを定義できます。

class EventUser < ActiveRecord::Base
  belongs_to :event
  belongs_to :user

  scope :active,   -> { where(active: true)  }
  scope :inactive, -> { where(active: false) } 
end

現在、ユーザーはアクティブなイベントと非アクティブなイベントの両方の種類のイベントを持つことができるため、次のように User モデルで関係を定義できます。

class User < ActiveRecord::Base
  has_many :active_event_users,   -> { active },   class_name: "EventUser"
  has_many :inactive_event_users, -> { inactive }, class_name: "EventUser"

  has_many :inactive_events, through: :inactive_event_user,
                             class_name: "Event",
                             source: :event
  has_many :active_events,   through: :active_event_users,
                             class_name: "Event",
                             source: :event
end

この手法の利点は、アクティブまたは非アクティブイベントの機能が EventUser モデルに属し、将来機能を変更する必要がある場合、1つだけで変更されることです。 place: EventUser モデル、および変更は他のすべてのモデルに反映されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top