Question

All I follow the tutorial to make a simple many to many example, http://hadiyahdotme.wordpress.com/2011/09/25/many-ways-to-do-many-to-many-hacker-notes/

I thought we only have to create another table "categorization " to make many-to-many relations between category and product model is enough! why should we do 'rails generate migration create_categories_products_join'

I can not understand, any idea can help me , thanks a lot!

Was it helpful?

Solution

Between category and product must be association (connection) so You must create special table for that.

If You want use has_and_belongs_to_many:

in models/product.rb:

...
has_and_belongs_to_many :categories, :join_table => :categories_products
...

in models/category.rb:

...
has_and_belongs_to_many :products, :join_table => :categories_products
...

in your migration file create_categories_products_join.rb

...
create_table :categories_products, :id => false do |t|
  t.references :product
  t.references :category
end
add_index :categories_products, [:product_id, :category_id]
add_index :categories_products, [:category_id, :product_id]
...

and remove categorization model rails d model categorization

If You want use has_many :through

in models/product.rb:

...
has_many :categorizations
has_many :categories, :through => :categorizations 
...

in models/category.rb:

...
has_many :categorizations
has_many :products, :through => :categorizations 
...

in models/categorization.rb

...
belongs_to :product
belongs_to :category
...

in migration file create_categorizations

...
create_table :categorizations do |t|
  t.references :product
  t.references :category
  #...
  t.timestamps
end
add_index :categorizations, :category_id
add_index :categorizations, :product_id
...

migration create_categories_products_join You can remove rails d migration create_categories_products_join

OTHER TIPS

Its just two examples. First one is about has_and_belongs_to_many second one is about has_many :through.

If you are going with has_many :through and categorization table there is no need to create another table categories_products.

Choose one of the methods and you are done. I would recommend has_many :through. Its more flexible.

When you have has and belongs to many (HABTM) relation you have to define a way to connect products to categories and vise versa. Thus, you should use join table.

In rails, when you code:

has_many :products, through: :categorizations

You should create a join table categorizations with reference to each one:

create_table "categorizations" do |t|
  t.integer  "category_id"
  t.integer  "product_id"
end

Then, you can access categories on specific product product.categories and products from category category.products

I suggest you to watch this RailsCast and review this code

Why do we need associations between models? Because they make common operations simpler and easier in your code.

A has_many :through association is often used to set up a many-to-many connection with another model.This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model.

For many to many we need to create a third model .i.e in your example

    create_table "categorizations" do |t|
    t.integer  "category_id"
    t.integer  "product_id"
    end

-------------Models-------------

   class Category < ActiveRecord::Base
   has_many :categorizations
   has_many :products, through: :categorizations
   end

   class Product < ActiveRecord::Base
   has_many :categorizations
   has_many :categories, through: :categorizations
   end

   class Categorization < ActiveRecord::Base
   belongs_to :product
   belongs_to :category
   end

Now creating join table in Rails 4 is cool see available methods -

Migration method to create_join_table creates a HABTM join table. A typical use would be:

create_join_table :products, :categories

You can pass the option :table_name when you want to customize the table name. For example:

create_join_table :products, :categories, table_name: :categorization

will create a categorization table.

create_join_table also accepts a block, which you can use to add indices (which are not created by default) or additional columns:

create_join_table :products, :categories do |t|
  t.index :product_id
  t.index :category_id
end

click here for more details

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top