How should I model these relationships?
I have a post model. Each post has a title and many snippets.
class Post < ActiveRecord::Base has_many :snippets end class Snippet < ActiveRecord::Base belongs_to :post attr_accessible :position, :post_id end
I want to have 4 different types of snippet i.e.:
- body (text)
- image (string)
- code (text)
- video (string)
Should I create four new models (called text, code, video and image) which extend the snippet model like so?:
class Text < Snipppet attr_accessible :body end class Image < Snippet attr_accessible :image end class Video < Snippet attr_accessible :title end class Code < Snippet attr_accessible code end
How can I refer to the content of each snippet in my view when each snippet can be one of 4 different things?
In my view I'd like to put something like this:
- for snippet in @post.snippets = place the content of the snippet here
I don't think it sounds like a good idea to have a "type" field on the snippet model as this would possibly lead to strong coupling of the database and the code. Is there some kind of rails magic that will help me out in this situation?
I kinda like the type field, actually. You could use the magic of single table inheritance, but it's well-known to be a fragile system that, surprise, includes a type field, anyway.
And then you could use the polymorphism solution, but seems a bit silly to have four different tables to represent almost exactly the same thing.
Honestly, using a simple type field and changing the interpretation based on that will probably give you the best results and fewest headaches.
As far as what you'd do in your template goes, that you can probably play by ear. One clean solution might be a simple helper to call like snippet_content which, based on the type field, will call the helper snippet_content_text or snippet_content_image or snippet_content_code or snippet_content_video. Or you can just do the if-then branching in the template, or refer to any number of partial templates (though be careful with that, since those can get slow when used unnecessarily).