Here is how you set up HABTM with a joining table.
My models are Tutorial and Category - a tutorial can have more than one category and vice versa.
Both models already existed and I wanted to create the relationship between them.
1: Create a migration for the joining table
The default table name should be the plural of the two models, in alphabetical order, separated by an underscore. (You can give it any name you want - you just need to include that later in the model)
class CreateCategoriesTutorials < ActiveRecord::Migration
def change
create_table :categories_tutorials do |t|
t.belongs_to :tutorial
t.belongs_to :category
end
end
end
2: Add the relationships to the models
Previously you would have done this (in the Tutorial model):
has_many :categories_tutorials, :dependent => :destroy
has_many :categories, :through => :categories_tutorials, :uniq => true
That is now simplified to this:
has_and_belongs_to_many :categories
If you have a custom table name then specifiy it like this:
has_and_belongs_to_many :categories, join_table: :my_category_tutorial_table
The Category model has:
has_and_belongs_to_many :tutorials
The CategoryTutorial model has:
belongs_to :category
belongs_to :tutorial
In my example I want to specify Categories when I create a Tutorial.
In order for this to work I need to allow the tutorials_controller to accept the category_ids parameter which is passed from the tutorial form.
At the bottom of the controller Rails has created this:
def tutorial_params
params.require(:tutorial).permit(:title, :description, :status)
end
I need to add category_ids and have it set up as an array
def tutorial_params
params.require(:tutorial).permit(:title, :description, :status, :category_ids => [])
end
That last step is critical - if you miss this then the associated rows are not created in the database.
For more information on HABTM take a look at:
http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
1 comment:
Could I please see the whole controller? I think I am missing the point in the create and edit methods. Thanks! I'm trying to do something similar.
Post a Comment