Une Person
peut avoir plusieurs Events
et chaque Event
peut avoir un enregistrement polymorphe Eventable
. Comment spécifier la relation entre la Person
et l’enregistrement Eventable
?
Voici les modèles que j’ai:
class Event true end class Meal eventable end class Workout eventable end
La question principale concerne la classe Person
:
class Person :events # is this correct??? end
Dois-je dire has_many :eventables, :through => :events
comme je l’ai fait ci-dessus?
Ou dois-je les épeler tous ainsi:
has_many :meals, :through => :events has_many :workouts, :through => :events
Si vous voyez un moyen plus facile d’accomplir ce que je suis après, je suis tout ouïe! 🙂
Tu dois faire:
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
Cela vous permettra de le faire:
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
Une autre option consiste à utiliser un modèle STI (Single Table Inheritance) ou MTI (Multi Table Inheritance), mais cela nécessite certaines retouches de table ActiveRecord / DB, mais cela peut aider d’autres utilisateurs à le trouver pour la première fois.
Voici la méthode STI dans Rails 3+: Votre concept Eventable devient une classe et nécessite une colonne de type
(quels rails se remplissent automatiquement pour vous).
class Eventable < ActiveRecord::Base has_one :event end
Ensuite, vos deux autres classes héritent de Eventable au lieu de AR :: Base
class Meal < Eventable end class Workout < Eventable end
Et votre object événement est fondamentalement le même, mais pas polymorphe:
class Event < ActiveRecord::Base belongs_to :person belongs_to :eventable end
Cela peut rendre certaines de vos autres couches plus confuses, si vous ne les avez jamais vues auparavant et que vous ne faites pas attention. Par exemple, vous pouvez accéder à un seul object Meal /eventable/1
/meals/1
et /eventable/1
si vous rendez les deux /eventable/1
extrémité disponibles dans les itinéraires et que vous devez connaître la classe que vous utilisez lorsque vous extrayez un object hérité ( indice: la méthode becomes
très utile si vous devez remplacer le comportement de rails par défaut)
Mais il s’agit d’une délimitation des responsabilités beaucoup plus nette que celle des applications, selon mon expérience. Juste un motif à considérer.