I have a has_many :through association setup between two tables (Post and Category). The reason I’m using has_many :through instead of HABTM is that I want to do some validation on the join table (PostCategory).
So I have 4 models in use here:
User:
has_many :posts
has_many :categories
Post:
belongs_to :user
has_many :post_categories
has_many :categories, :through => :post_categories
Category:
belongs_to :user
has_many :post_categories
has_many :posts, :through => :post_categories
PostCategory:
belongs_to :post
belongs_to :category
Basically what I want is: Users can create posts, users can also create their own categories. A user can then categorize posts (not just their posts, any posts). A post can be categorized by many different users (in different ways potentially), and a category could contain many different posts (A user could categorize N posts under a specific category of theirs).
Here’s where it gets a little bit tricky for me (I’m a Rails noob).
A post can ONLY belong to ONE category for a given user. That is, a post CANNOT belong to more than ONE category for any user.
What I want to be able to do is create a validation for this. I haven’t been able to figure out how.
I’ve tried things like (inside PostCategory)
validates_uniqueness_of :post_id, :scope => :category_id
But I realize this isn’t correct. This would just make sure that a post belongs to 1 category, which means that after one user categorizes the post, no other user could.
Really what I’m looking for is how to validate this in my PostCategory model (or anywhere else for that matter). I’m also not against changing my db schema if that would make things easier (I just felt that this schema was pretty straight forward).
Any ideas?
Option 1 : use a
before_save. In it, do a SQL look up to make sure a post with a similar category for your user doesn’t exist (take care that on edit, you’ll have to make sure you don’t look-up for the current Post that is already in the DB)Option 2 : custom validators :
http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#custom-validators
Never used them, but sounds like it can do what you want