In my project, I have the following models
Content -> stores title and body text
ImageAsset -> title, description, paperclip file
ImageLinker -> to link a content with many images and vice versa, using has_many :through
The same way I have linked
FileAsset model with Content using FileLinker model
Category model with Content using Categorization model
Now first my question, is this how a good rails develop make the relationships?
second, there is one another need that the above setup doesn’t meet. i.e., There are several types of content like event, project, article, blog, receipe. And each of these content types have a need for additional set of fields in their model like event content has title, description and additionally event time and date.
My initial thought was to move to postgresql and use hstore to store the arbitrary properities based on content type. But
2a. I am not sure if this is the right approach
2b. I don’t know how I can implement it, even if this is a right approach. ANy guidance on implementing will be much helpful.
@shankard, I’m trying to understand your situation a little more. What is the purpose of ImageLinker as opposed to just using an Image model? You can use a has_and_belongs_to_many for Content and Images and just be done. (assuming an image can belong to more than one Content object.)
As far as your second need, I did something similar to this at Tribeca Film, I used a “Container” model that could then hold objects of the other models. So for example, a Container has_many :events; has_many :projects, etc. So you’d make models for each of the types of content you mentioned. Obviously you can substitute the name Content for Container. Then your Project, Blog etc would simply belong_to :content
I’m somewhat just brainstorming aloud, so there could be better ways to handle this, but my instinct is that an ImageLinker model is completely unnecessary since you’re relating Content with Image this doesn’t seem to be a use case for the :through aspect. You’ve probably seen this, but I would encourage you to revisit the following page for a very clear walkthrough of Rails associations. I’ve been doing this for a few years and I still reference this page when I face a question like yours in my own projects: http://guides.rubyonrails.org/association_basics.html
I hope this helped, but hopefully it be a starting point for some others to add their expertise. I am far from expert!
@briandear thanks for your reply. Regarding the ImageLinker, I need them because each Image needs a title and description and one content has many such images. Apparently, I understood that paperclip files doesn’t have these two fields. So I’m using the Imagemodel to attach one file with a title and a description and ImageLinker to attach multiple image models to the content model. I hope this is ok? please correct me if I’m wrong.
for my second question, I somehow feel that having a dedicated table for each of the content types is a over kill. Because all contents have title and body and by default, so I am attaching this to the Content model. Then there is a Blog content type which doesn’t have any extra field whereas Event content type has extra fields like time and date. So the point that I am trying to make is that about 10//15 content types that I am trying to create doesn’t have any extra fields so creating a model for each content type will mean that I have about 10 models that doesn’t have any fields at all.
In this context, I am trying to use psql hstore. But I am looking for some guidance on how to build the model with hstore and forms in views.
Regarding your content types, then you can easily use one model as you proposed, then have a field that just identifies the content type. Easy-peezy and probably a better plan given what you’ve said.
As far as paperclip not having those fields, I’m not completely familiar with Paperclip, since I use Carrierwave, however they appear to work similarly. From my experience, all I do is have an Image model with all the fields that you could possibly want (the ones you mentioned, for instance.) All paperclip is doing is storing the file data in a string field. Paperclip doesn’t care about the other fields within that image object.
So you have this: Content has_and_belongs_to_many :images) Image has_and_belongs_to_many :contents – the paperclip part of this is really only going to cover the image:string field within the Image model.
Now, if you’re handling meta-data embedded within an image file with Paperclip, then I have no idea how to do that, but it seems in your use case, the above solution should not only work, but it’s a very common pattern. Basically, to summarize: Paperclip doesn’t care about the other fields in your Image object – it only cares about the actual field within which the image is referenced.
Some of the Thoughtboters might be able to expand on the Paperclip stuff, but generally using a single Image model does everything you want. Using a separate model just for image information is unnecessary. I could be misunderstanding your Paperclip concerns, so I would invite others to correct me if I’m wrong!
The ImageLinker model doesn’t need to be there because the has_and_belongs_to_many does that for you. That’s the entire purpose of that type of Rails relationship.
Good luck! I hope I’ve helped, if not, my apologies!