In both approach, the intermediate table is going to hold the relation and also will yield the same result but when to choose what, still puzzled?
Pointers to choose has_and_belongs_to_many. If you choose not to:
Access the model which holds the relationship
Have any validations for the association
Read the associaton through the relationship
To make it more clear, lets try to restrict the number of comments for a post.
This as well can be implemented in many ways but we (atleast I initally went with this approach) naturally tend to add logic in Post class
classPosthas_many:commentables,has_many:comments,:through=>:commentables,:before_add=>:check_comment_limitprivatedefcheck_comment_limit(comment)#If you want to stop comment getting added to post, you have to raise an error.raise'Comment limit reached'ifself.comments.count=5endend
Another approach to tackle this is to add validation logic to the Comment class
classCommenthas_many:commentables,has_many:posts,through=>:commentablesvalidate:check_comment_limitprivatedefcheck_comment_limitcomment_count=self.posts.comment.counterrors.add(:posts,'Comment limit reached')ifcomment_count=5#If you want to stop comment getting added to post, you have to raise an error.raise'Comment limit reached'ifcomment_count=5endend
In both the approaches we have to raise an exception to prevent the comment from getting added to the post. I felt these approaches are not the conventional way of doing things, I went back and read the rails guide on association and rewrote the validation logic in the relation model which holds the association.