Best way to make an HABTM association via console

242 views Asked by At

I have this scenario:

class Order < ActiveRecord::Base
  has_and_belongs_to_many :products
end

class Product < ActiveRecord::Base
  has_and_belongs_to_many :orders
end

class CreateJoinTableOrdersProducts < ActiveRecord::Migration
  def change
    create_join_table :orders, :products do |t|
      t.index [:order_id, :product_id]
      t.index [:product_id, :order_id]
      t.decimal :price, precision: 8, scale: 2
      t.integer :quantity, default: 1      
    end
  end
end

Now, I need to add some records using the command line:

This works fine:

Order.first.products << Product.first

But, I need to add some more fields, like: price, quantity...

How can I do this?

1

There are 1 answers

4
max On BEST ANSWER

Rails has the association.create and .build methods which allows you to create associated models on the fly:

Order.first.products.create(price: 999)

But as @test has pointed out you need to use has_many_through instead of has_and_belongs_to_many when the join table contains its own data.

has_and_belongs_to_many is used for a straight many-to-many relationship. There is no straightforward way to get the additional data such as price or quantity in a HABM relationship which is just built on a join table with the IDs of the joined models. The rails guides explain this pretty well.

class Order < ActiveRecord::Base
  has_many :row_items
  has_many :products, though: :row_items
end

class Product < ActiveRecord::Base
  has_many :row_items
  has_many :orders, though: :row_items
end

class RowItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :order
end

You would also need to create the correct table:

rails g migration CreateRowItem product:belongs_to order:belongs_to price:decimal ...

You can then create associated records via:

Order.first.row_items.create(price: 999, product: product)