両方の新しいRubyとRailsしかし、私は今までに教育を受けた本です。
EventUserという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
これは「Rails way」に反するようです。誰も私を啓発できますか、これは今夜(今朝)長い間私を悩ませてきましたか?
このようなものをユーザーモデルに追加してみませんか?
has_many :active_events, :through => :event_users,
:class_name => "Event",
:source => :event,
:conditions => ['event_users.active = ?',true]
その後、以下を呼び出すだけで、ユーザーのアクティブなイベントを取得できるはずです。
User.first.active_events
ミラノノボタには良い解決策がありますが、:conditions
は非推奨になり、:conditions => ['event_users.active = ?',true]
ビットは、とにかくRailsとにかく思えます。このようなものが好きです。
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はexplicitly user_eventsテーブルの呼び出しではありませんが、そのテーブルは必要な結合のためにSQL 暗黙的に含まれています。したがって、検索条件でそのテーブルを引き続き使用できます。
u.events.find(:all, :conditions => ["user_events.active = ?", true])
もちろん、この検索を何度も実行する予定がある場合は、Milan Novotaが提案するように別の関連付けを指定してください。ただし、そのようにするためのrequirementはありません。
実際、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つの場所でのみ変更されることです:EventUser
model、および変更は他のすべてのモデルに反映されます。