Person
は多くのEvents
を持つことができ、各Event
は1つのポリモーフィックなEventable
レコードを持つことができます。 Person
レコードとEventable
レコードの関係を指定するにはどうすればよいですか?
これが私が持っているモデルです:
class Event < ActiveRecord::Base
belongs_to :person
belongs_to :eventable, :polymorphic => true
end
class Meal < ActiveRecord::Base
has_one :event, :as => eventable
end
class Workout < ActiveRecord::Base
has_one :event, :as => eventable
end
主な質問はPerson
クラスに関するものです。
class Person < ActiveRecord::Base
has_many :events
has_many :eventables, :through => :events # is this correct???
end
上記のようにhas_many :eventables, :through => :events
と言いますか?
または、次のようにすべてを綴る必要がありますか?
has_many :meals, :through => :events
has_many :workouts, :through => :events
私が求めていることを達成するためのより簡単な方法を見つけたら、私はすべての耳です! :-)
あなたはしなければならない:
class Person < ActiveRecord::Base
has_many :events
has_many :meals, :through => :events, :source => :eventable,
:source_type => "Meal"
has_many :workouts, :through => :events, :source => :eventable,
:source_type => "Workout"
end
これにより、次のことが可能になります。
p = Person.find(1)
# get a person's meals
p.meals.each do |m|
puts m
end
# get a person's workouts
p.workouts.each do |w|
puts w
end
# get all types of events for the person
p.events.each do |e|
puts e.eventable
end
これの別のオプションは、単一テーブル継承(STI)またはマルチテーブル継承(MTI)パターンを使用することですが、これにはActiveRecord/DBテーブルのやり直しが必要ですが、これは、初めて設計している他の人がこれを見つけるのに役立つ場合があります。
これがRails 3+のSTIメソッドです:あなたのEventableコンセプトはクラスになり、type
列(Railsが自動的に入力されます)。
class Eventable < ActiveRecord::Base
has_one :event
end
次に、AR :: Baseの代わりにEventableから他の2つのクラスinherit
class Meal < Eventable
end
class Workout < Eventable
end
また、イベントオブジェクトは基本的に同じですが、ポリモーフィックではありません。
class Event < ActiveRecord::Base
belongs_to :person
belongs_to :eventable
end
これは、これまでにこれを見たことがなく、注意しない場合、他のレイヤーのいくつかをより混乱させる可能性があります。たとえば、ルートで両方のエンドポイントを使用できるようにすると、/meals/1
と/eventable/1
で単一のMealオブジェクトにアクセスでき、継承をプルするときに使用しているクラスを認識する必要があります。オブジェクト(ヒント:becomes
method は、デフォルトのRails動作)をオーバーライドする必要がある場合に非常に便利です。
しかし、私の経験では、これはアプリの拡張に伴う責任のはるかに明確な説明です。考慮すべき単なるパターン。