I have a 3 models: quote, customer, and item. Each quote has one customer and one item. I would like to create a new quote, a new customer, and a new item in their respective tables when I press the submit button. I have looked at other questions and railscasts and either they don't work for my situation or I don't know how to implement them.
quote.rb
class Quote < ActiveRecord::Base
  attr_accessible :quote_number
  has_one :customer
  has_one :item
end
customer.rb
class Customer < ActiveRecord::Base
  attr_accessible :firstname, :lastname
  #unsure of what to put here
  #a customer can have multiple quotes, so would i use has_many or belongs_to?
  belongs_to :quote
end
item.rb
class Item < ActiveRecord::Base
  attr_accessible :name, :description
  #also unsure about this
  #each item can also be in multiple quotes
  belongs_to :quote
quotes_controller.rb
class QuotesController < ApplicationController
  def index
    @quote = Quote.new
    @customer = Customer.new
    @item = item.new
  end
  def create
    @quote = Quote.new(params[:quote])
    @quote.save
    @customer = Customer.new(params[:customer])
    @customer.save
    @item = Item.new(params[:item])
    @item.save
  end
end
items_controller.rb
class ItemsController < ApplicationController
  def index
  end
  def new
    @item = Item.new
  end
  def create
    @item = Item.new(params[:item])
    @item.save
  end
end
customers_controller.rb
class CustomersController < ApplicationController
  def index
  end
  def new
    @customer = Customer.new
  end
  def create
    @customer = Customer.new(params[:customer])
    @customer.save
  end
end
my form for quotes/new.html.erb
<%= form_for @quote do |f| %>
  <%= f.fields_for @customer do |builder| %>
    <%= label_tag :firstname %>
    <%= builder.text_field :firstname %>
    <%= label_tag :lastname %>
    <%= builder.text_field :lastname %>
  <% end %>
  <%= f.fields_for @item do |builder| %>
    <%= label_tag :name %>
    <%= builder.text_field :name %>
    <%= label_tag :description %>
    <%= builder.text_field :description %>
  <% end %>
  <%= label_tag :quote_number %>
  <%= f.text_field :quote_number %>
  <%= f.submit %>
<% end %>
When I try submitting that I get an error:
Can't mass-assign protected attributes: item, customer
So to try and fix it I updated the attr_accessible in quote.rb to include :item, :customer but then I get this error:
Item(#) expected, got ActiveSupport::HashWithIndifferentAccess(#)
Any help would be greatly appreciated.
To submit a form and it's associated children you need to use accepts_nested_attributes_for
To do this, you need to declare it at the model for the controller you are going to use (in your case, it looks like the Quote Controller.
class Quote < ActiveRecord::Base
  attr_accessible :quote_number
  has_one :customer
  has_one :item
  accepts_nested_attributes_for :customers, :items
end
Also, you need to make sure you declare which attributes are accessible so you avoid other mass assignment errors.
If you want add info for diferent models i suggest to apply nested_model_form like this reference: http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast.
This solution is very simple and cleanest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With