Setting join table attribute :has_many :through association in Rails ActiveRecord
I needed to set an attribute on a join table or in ActiveRecord, the :through model as an atomic save action. Let’s set the scene: I have a Product and a User which has a many-to-many relationship since a Product can have many Users and a User can have many Products.
Typically, in a database we might have a table product, user and product_user. In Rails I created an association class called Collaborators since it fit my domain better. Additionally the Collaborators class has one attribute is_admin which indicates the User (or Collaborator actually) is an administrator for the particular Product.
One of the business rules in the application was that if a User creates a new Product then they are automatically an administrator for that Product. My dilemma was how to create the new Product, associate it correctly with the User *and* set is_admin to true all in one nice and neat command?
The answer, it turns out, is straightforward and elegant. I am fairly new to Rails myself, so I understand if this might appear a little overwhelming if you are also just starting out. I have included a set of useful references at the end of this post to help you on your way.
class Product< ActiveRecord::Base has_many :collaborators has_many :users, :through => :collaborators end
class User< ActiveRecord::Base has_many :collaborators has_many :products, :through => :collaborators end
class Collaborator < ActiveRecord::Base belongs_to :product belongs_to :user end
Once you have the above ActiveRecord models setup all you need to do is execute the following code to save a new Product, associate a User as a Collaborator and set them as an administrator for the Product.
#assume we have the product and current_user instance already set product.save && product.collaborators.create(:user => current_user, :is_admin => true)
Useful Resources and Docs for ActiveRecord Associations
Has Many Through Association
ActiveRecord::Base Documentation