HABTM problem not saving all associations


#1

Hello all,

I have an Order object that has and belongs to many Products and has
and belongs to many Loan Types. This is so I can select multiples of
each in my order entry screen via checkbox groups.

I’m having some trouble with saving multiple HABTM associations for a
single model object; only the first HABTM association declared in the
model will save during the initial @order.save in the create action in
my orders_controller.rb code below.

If the order is then updated via an edit action, all selected
associations will save correctly. If you notice in the
development.log dump, I’m passing product_ids and loan_type_ids arrays
back to the controller properly. Inspecting the @order object during
a breakpointer session shows the related object are available for
saving, but for some reason, ActiveRecord does not want to save the
second association class at the beginning.

Any ideas what I’m doing wrong?

I’m using Ruby 1.8.2, Rails 1.0 and MySQL 5.0.16 on both Ubuntu Breezy
and Mac OS X Tiger 10.4.3. Ruby and MySQL were built from source on
both as well.

Thanks for your time and attention.

Keith Veleba

—CUT HERE—

class Order < ActiveRecord::Base
belongs_to :account
has_and_belongs_to_many :loan_types
has_and_belongs_to_many :products
has_many :order_notes
has_one :structure_type
has_one :order_state
end

class Product < ActiveRecord::Base
has_and_belongs_to_many :orders
end

class LoanType < ActiveRecord::Base
has_and_belongs_to_many :orders
end

chunk of orders_controller.rb:

def create
@order = Order.new(params[:order])
@order.products = Product.find(params[:product_ids]) if
params[:product_ids]
@order.loan_types = LoanType.find(params[:loan_type_ids]) if
params[:loan_type_ids]

if @order.save
flash[:notice] = ‘Order was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

def update
@order = Order.find(params[:id])
@order.products = Product.find(params[:product_ids]) if
params[:product_ids]
@order.loan_types = LoanType.find(params[:loan_type_ids]) if
params[:loan_type_ids]
if @order.update_attributes(params[:order])
flash[:notice] = ‘Order was successfully updated.’
redirect_to :action => ‘show’, :id => @order
else
render :action => ‘edit’
end
end

chunk of _form.rhtml for orders:

Loan Type (check all that apply) <% for product in @products %> checked="checked"<% end %> > <%= product.title %>

<% end %>

Products (check all that apply) <% for loan_type in @loan_types %> checked="checked"<% end %> > <%= loan_type.name %>

<% end %>

chunk of log/development.log:

Processing OrdersController#create (for 127.0.0.1 at 2006-01-05
13:15:11) [POST]
Parameters: {“commit”=>“Create”, “product_ids”=>[“1”, “2”, “3”],
“loan_type_ids”=>[“1”, “2”, “4”], “order”=>{“city”=>"",
“loan_id_2”=>"", “borrower_first_name”=>"", “borrower_last_name”=>"",
“loan_id_3”=>"", “zip”=>"", “account_id”=>“10000”,
“structure_type_id”=>“1”, “builder_name”=>"",
“coborrower_first_name”=>"", “subdivision”=>"", “block”=>"",
“lot”=>"", “zip_plus_4”=>"", “address_line_1”=>“dfsdfsdf”,
“other_information”=>"", “coborrower_last_name”=>"",
“loan_amount”=>"", “address_line_2”=>“fddssdf”, “order_state_id”=>“1”,
“parcel”=>"", “builder_phone”=>"", “state”=>"", “loan_id_1”=>"",
“year_built”=>""}, “action”=>“create”, “controller”=>“orders”}
Order Columns (0.006320) SHOW FIELDS FROM orders
Product Load (0.000749) SELECT * FROM products WHERE (products.id
IN (‘1’,‘2’,‘3’))
SQL (0.000181) BEGIN
Product Columns (0.001374) SHOW FIELDS FROM products
SQL (0.000184) COMMIT
LoanType Load (0.000704) SELECT * FROM loan_types WHERE
(loan_types.id IN (‘1’,‘2’,‘4’))
SQL (0.000172) BEGIN
LoanType Columns (0.001363) SHOW FIELDS FROM loan_types
SQL (0.000169) COMMIT
SQL (0.000124) BEGIN
SQL (0.000930) INSERT INTO orders (city,
coborrower_phone_number, created_on, loan_id_2,
borrower_first_name, borrower_last_name, latitude, loan_id_3,
zip, account_id, structure_type_id, updated_on,
builder_name, coborrower_first_name, borrower_phone_number,
address_line_1, block, lot, subdivision, zip_plus_4,
address_line_2, coborrower_last_name, loan_amount,
other_information, longitude, order_state_id, parcel,
builder_phone, loan_id_1, state, year_built) VALUES(’’, NULL,
‘2006-01-05 13:15:11’, ‘’, ‘’, ‘’, NULL, ‘’, ‘’, 10000, 1, ‘2006-01-05
13:15:11’, ‘’, ‘’, NULL, ‘dfsdfsdf’, ‘’, ‘’, ‘’, ‘’, ‘fddssdf’, ‘’,
‘’, ‘’, NULL, 1, ‘’, ‘’, ‘’, ‘’, NULL)
loan_types_orders Columns (0.001317) SHOW FIELDS FROM
loan_types_orders
SQL (0.000496) INSERT INTO loan_types_orders (order_id,
loan_type_id) VALUES (5, 1)
loan_types_orders Columns (0.001122) SHOW FIELDS FROM
loan_types_orders
SQL (0.000471) INSERT INTO loan_types_orders (order_id,
loan_type_id) VALUES (5, 2)
loan_types_orders Columns (0.001477) SHOW FIELDS FROM
loan_types_orders
SQL (0.000456) INSERT INTO loan_types_orders (order_id,
loan_type_id) VALUES (5, 4)
SQL (0.000181) COMMIT

Keith Veleba
keith (at) veleba.net


#2

This might explain your problem…

http://dev.rubyonrails.org/ticket/3213


#3

That’s it! Thanks for your help, I really appreciate it.

On 1/6/06, Kevin O. removed_email_address@domain.invalid wrote:

Keith Veleba
keith (at) veleba.net