2010-01-22 3 views
0

Je travaille sur une application qui permet aux utilisateurs d'associer des images à des événements spécifiques. Les événements sont la propriété d'un utilisateur. La solution facile serait bien sûr:Modélisation des données Rails - alternatves à has_many: through, polymorphisme donné?

 
class Image < ActiveRecord::Base 
    belongs_to :event 
end 

class Event < ActiveRecord::Base 
    has_many :images 
    belongs_to :user 
end 

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

Except! Il y a un problème. Je veux aussi que mes utilisateurs puissent posséder des images directement, sans événement intermédiaire. Si j'utilise l'association polymorphe "conventionnellement" ici, alors évidemment user.images ne fonctionnera pas correctement. Devrais-je simplement tenir mon nez, utiliser un :as => :event_images pour désambiguïser, et définir user.all_images si ce besoin se présente? Devrais-je avoir toutes les images détenues directement par les utilisateurs et éventuellement associées à des événements en quelque sorte? (Avec, bien sûr, une validation pour assurer la cohérence ... mais cela semble code-malodorant.) Y at-il une troisième solution qui est plus jolie que l'un ou l'autre?

Répondre

0

Je trouve souvent utile d'oublier le DSL ActiveRecord et de travailler directement avec le modèle de données lors de la définition de relations complexes. Une fois le modèle de données correct, vous pouvez le mapper en instructions de modèle.

Il n'est pas tout à fait clair à partir de votre question si les images peuvent être la propriété d'un utilisateur ou un événement, si elles peuvent être possédées par les deux en même temps. Ce problème déterminera le modèle de données que vous utilisez.

Si une image peut appartenir à la fois, la table d'image aura besoin d'une référence à la fois un user_id et un event_id, qui peuvent avoir besoin d'être annulable selon votre cas d'utilisation (l'utilisateur ou l'événement en option des relations). Si l'image ne peut être possédée que par un, vous pouvez mettre en place une sorte de relation propriétaire polymorphe qui mappe les propriétaires à la bonne table propriétaire (owner_id, owner_type etc etc).

En supposant qu'il peut appartenir à la fois:

class Image < ActiveRecord::Base 
    belongs_to :event 
    belongs_to :user 
end 

class Event < ActiveRecord::Base 
    has_many :images 
    belongs_to :user 
end 

class User < ActiveRecord::Base 
    has_many :events 
    has_many :images 
    has_many :event_images, :through => :events, :class_name => "Image" 
end 
Questions connexes