I know there's a lot of open questions regarding this around here already but none really helped me.
My main model is being saved properly, all the data is in the post-data, but it just doesn't save the nested models!
Thanks heaps.. Is it anything about the permitted parameters or attr_accessors? Something I suspect.. I didn't really find any documentation on that..
This is my code:
products_controller.rb
def product_params
params.require(:product).permit(:title, :description, :netprice, :vat, :price, :unit_count, :unit, :category, :img, :origin, :originid, :producer, :stock, :discount, :stories_attributes, :origins_attributes, :id)
end
end
def new
#product = Product.new
3.times { #product.stories.build }
#product.origins.build
#categories = []
Category.all.each do |category|
#categories.push([category.name, category.name])
end
end
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render action: 'show', status: :created, location: #product }
else
format.html { render action: 'new' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
origin.rb
class Origin < ActiveRecord::Base
belongs_to :product
end
product.rb
class Product < ActiveRecord::Base
attr_accessor :stories_attributes, :origins_attributes
has_many :stories
has_many :origins
accepts_nested_attributes_for :stories, allow_destroy:true, :reject_if => lambda { |a| a[:text].blank?}
accepts_nested_attributes_for :origins, allow_destroy:true, :reject_if => lambda {|a| a[:city].blank?}
story.rb
class Story < ActiveRecord::Base
belongs_to :product
end
relevant part of the form
<section class="product-story-section">
<%= f.fields_for :stories do |builder| %>
<fieldset>
<%= builder.label :yindex, "Y-Index" %><br>
<%= builder.text_field :yindex %><br>
<%= builder.label :description, "Story-Text" %><br>
<%= builder.text_area :description %><br>
<%= builder.label :img, "Bild-URL" %><br>
<%= builder.text_field :img %><br>
<%= builder.hidden_field :productid, value:"1" %><br>
</fieldset>
<% end %>
</section>
<hr>
<%= f.fields_for :origins do |builder| %>
<fieldset>
<%= builder.label :city, "Stadt" %><br>
<%= builder.text_field :city %><br>
<%= builder.label :country, "Land" %><br>
<%= builder.text_area :country %><br>
<%= builder.label :geolat, "Geolocation Latitude" %><br>
<%= builder.text_field :geolat %><br>
<%= builder.label :geolng, "Geolocation Longitude" %><br>
<%= builder.text_field :geolng %><br>
</fieldset>
<% end %>
Started POST "/products" for 127.0.0.1 at 2013-12-24 21:01:16 +0100
Processing by ProductsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"90MXIlzOQg6AcTwwYOkfNsfPuSt1/9UHjqZwHVRnET4=", "product"=> {"title"=>"9", "description"=>"9", "netprice"=>"9", "vat"=>"9", "price"=>"9", "unit_count"=>"9", "unit"=>"9", "img"=>"", "originid"=>"99", "origin"=>"", "producer"=>"9", "stock"=>"9", "discount"=>"9", "stories_attributes"=>{"0"=>{"yindex"=>"9", "description"=>"9", "img"=>"9", "productid"=>"1"}, "1"=>{"yindex"=>"9", "description"=>"9", "img"=>"9", "productid"=>"1"}, "2"=>{"yindex"=>"9", "description"=>"9", "img"=>"9", "productid"=>"1"}}, "origins_attributes"=>{"0"=>{"city"=>"9", "country"=>"", "geolat"=>"9", "geolng"=>"9"}}}, "commit"=>"Create Product"}
Unpermitted parameters: img, productid
Unpermitted parameters: img, productid
Unpermitted parameters: img, productid
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO `products` (`created_at`, `description`, `discount`, `img`, `netprice`, `origin`, `originid`, `price`, `producer`, `stock`, `title`, `unit`, `unit_count`, `updated_at`, `vat`) VALUES ('2013-12-24 20:01:16', '9', 9.0, '', 9.0, '', 99, 9.0, '9', 9, '9', '9', 9, '2013-12-24 20:01:16', 9.0)
(0.5ms) COMMIT
Redirected to http://localhost:3000/products/1
Completed 302 Found in 46ms (ActiveRecord: 0.9ms)
New error msg
`attr_accessible` is extracted out of Rails into a gem. Please use new recommended protection model for params(strong_parameters) or add `protected_attributes` to your Gemfile to use old one.
You have an extra end in your product_params method. This should have raised an error.
You also need to add stories and origins attributes to the permit list:
def product_params
params.require(:product).permit(:title, :description, :netprice, :vat, :price, :unit_count, :unit, :category, :img, :origin, :originid, :producer, :stock, :discount, stories_attributes: [:yindex, :description, :image], origins_attributes: [ :city, :country, :geolat], :id)
end
Update: Add missing attributes to the permit list on stories_attributes and origins_attributes:
def product_params
params.require(:product).permit(:title, :description, :netprice, :vat, :price, :unit_count, :unit, :category, :img, :origin, :originid, :producer, :stock, :discount, stories_attributes: [:yindex, :description, :img, :product_id], origins_attributes: [ :city, :country, :geolat, :geolng], :id)
end
Second update:
You also need to update your product model as follows:
class Product < ActiveRecord::Base
attr_accessible :stories_attributes, :origins_attributes
...
end
Replace attr_accessor with attr_accessible. attr_accessible should be used to allow attributes to mass assignment.
In your controller's create action:
# ProductsController
def create
#product = Product.new(product_params)
...
end
Your product_params definitely contains stories_attributes and origins_attributes and are passed to the Product.new method correctly, but because their attributes are not allowed to mass assignment you are not seeing associated stories and origins created. Note that attr_accessor, a Ruby method, only defines getters and setters for the attributes but does not allow for mass assignment.
Related
I have a form, that is saving the main attribute, but not its nested attributes. I have dug into a lot of documents, and seem to be doing things correctly, but still get an error that my nested attributes "must exist".
My interview attributes are saving correctly to the database, but my logs show "Unpermitted parameters: student, parents"
My code is modified for brevity, but I will still try to be thorough enough to get some direction as to what might be going wrong ...
Models (which I include accepts_nested_attributes for :student, :parents)
:student is singular since it has a has_one relationship
:parents is plural since it has a has_many relationship
class Interview < ApplicationRecord
has_one :student
has_many :parents
accepts_nested_attributes_for :student, :parents
end
class Student < ApplicationRecord
belongs_to :interview
end
class Parent < ApplicationRecord
belongs_to :interview
end
Controller
class InterviewsController < ApplicationController
def index
#interviews = Interview.all
end
def show
#interview = Interview.find(params[:id])
end
def new
#interview = Interview.new
#interview.build_student
2.times { #interview.parents.build }
end
def create
#interview = Interview.new(interview_params)
if #interview.save
redirect_to #interview
else
render :action => 'new'
end
end
private
def interview_params
params.require(:interview).permit(:date_today, :date_contact, :purpose_of_call, :problems_start_date, :cause, :violence, :running_away, :police_contact, :suicide, :self_harm, :other_info, :testing, :hospitalization, :medications, :school_problems, :teacher_relationships, :parent_goals, :notes,
student_attributes: [:id, :name, :age, :height, :weight, :dob, :interview_id],
parents_attributes: [:id, :name, :relationship, :parentage, :address, :phone_home, :phone_work, :phone_mobile, :phone_mobile, :email, :employer, :notes, :interview_id] )
end
end
Form (important bits)
<%= form_for(#interview) do |f| %>
<p class="inline">
<%= f.label :date_today, 'Today\'s Date' %>
<%= f.date_select(:date_today, :order => [:month, :day, :year], :start_year => 2000, :end_year => Date.today.year) %>
</p>
<p class="inline float_right">
<%= f.label :date_contact, 'Initial Contact' %>
<%= f.date_select(:date_contact, :order => [:month, :day, :year], :start_year => 2000, :end_year => Date.today.year) %>
</p>
<%= f.fields_for :student do |student_form| %>
<p><%= student_form.text_field :name, placeholder: 'Name' %></p>
<p class="inline">
<%= student_form.label :age %>
<%= student_form.text_field :age %>
</p>
<p class="inline">
<%= student_form.label :height %>
<%= student_form.text_field :height %>
</p>
<p class="inline">
<%= student_form.label :weight %>
<%= student_form.text_field :weight %>
</p>
///// removed for brevity /////
<% end %>
<%= f.fields_for :parents do |parent_form| %>
<%= render 'parents', :f => parent_form %>
<% end %>
Parent Partial
<p>
<%= f.label :name, 'Name' %>
<%= f.text_field :name %>
</p>
//// and more of the same /////
Routes
resources :interviews do
resources :student
resources :parents
end
The website form (at it's current state) can be found here: www.compassconsultingwi.com/interviews/new
and the link to the github can be found here: https://github.com/plantoteachme/compassconsultingwi
Params returns this ..
Parameters: {"utf8"=>"✓", "authenticity_token"=>"nU4WM2RO5GJd36eaSLHMxhRQCOnY8EPjDhUdFBHlYGkcw6H7/Oc5y7kFx0HMU9nm5cc47ZZZBDW6oQ2QNF5yhA==", "interview"=>{"date_today(2i)"=>"11", "date_today(3i)"=>"16", "date_today(1i)"=>"2016", "date_contact(2i)"=>"10", "date_contact(3i)"=>"23", "date_contact(1i)"=>"2016", "student"=>{"name"=>"John", "age"=>"12", "height"=>"5 feet", "weight"=>"123 lbs", "dob(2i)"=>"3", "dob(3i)"=>"13", "dob(1i)"=>"2004", "strengths"=>"Great with his siblings", "weaknesses"=>"Lazy", "likes"=>"Food", "dislikes"=>"Chores", "medical_prolems"=>"ADD", "religous_training"=>"Catholic", "ethnic_issues"=>"none", "grade_level"=>"6"}, "parents"=>{"name"=>"Jamie", "relationship"=>"Mom", "parentage"=>"Strict", "address"=>"Miwaukee Wi", "phone_home"=>"555-1000", "phone_work"=>"555-1001", "phone_mobile"=>"555-1002", "email"=>"jj#jj.com", "employer"=>"Googleer", "notes"=>"PhD in Computer Science"}, "purpose_of_call"=>"Depression causing suicidal tendencies", "problems_start_date"=>"When we moved from Nigeria last year", "cause"=>"Relocating", "violence"=>"none", "running_away"=>"no", "police_contact"=>"no", "suicide"=>"Hasn't acted on it, but talks about it", "self_harm"=>"Minor bruising from \"sports\"", "other_info"=>"", "testing"=>"Yes, for ADD", "hospitalization"=>"no", "medications"=>"Regeline", "school_problems"=>"Getting bullied", "teacher_relationships"=>"Strained", "parent_goals"=>"Improve self awareness", "notes"=>"Our family was in Nigeria for mission work"}, "button"=>""}
Unpermitted parameters: student, parents
Try to use cocoon gem.
You can build a model object using link_to_add_association method of cocoon gem.
Also, you can remove object using link_to_remove_association
A fully working example here: https://github.com/nathanvda/cocoon/wiki/ERB-examples
I'm working on an app that has and agency which has many branches and both the agency and the branches can have addresses. I have created the models for them as shown below:
# agency.rb
has_many :branches
has_one :address
accepts_nested_attributes_for :branches, reject_if: :all_blank, allow_destroy: true
accepts_nested_attributes_for :address, reject_if: :all_blank, allow_destroy: true
# branch.rb
belongs_to :agency
has_one :address
accepts_nested_attributes_for :address, reject_if: :all_blank
# address.rb
belongs_to :agency
belongs_to :branch
I have an agency form which should allow me to create/edit an agency and it's address as well as add/edit/delete branches and their addresses too.
Here is the agency form:
<%= form_for(#agency) do |f| %>
<div class="box-body">
# errors and messages etc etc ...
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name, class: 'form-control' %>
</div>
# more agency fields
<%= f.fields_for :address do |address| %>
<%= render 'addresses/address_fields', f: address %>
<% end %>
#other fields which all work fine
<div id="branches">
<%= f.fields_for :branches do |branch| %>
<%= render 'branch_fields', f: branch %>
<% end %>
<div class="links">
<%= link_to_add_association 'add branch', f, :branches %>
</div>
</div>
</div>
<%= f.submit 'Save Changes', class: 'btn btn-primary' %>
<% end %>
Here are the branch fields (partial form):
# branch name ...
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
# I will explain this bit below
<% if f.object.new_record? %>
<% f.object.build_address %>
<% end %>
###
<%= f.fields_for :address do |address| %>
<%= render 'addresses/address_fields', f: address %>
<% end %>
# other branch fields that work fine
<%= link_to_remove_association "remove branch", f %>
And here is the agencies controller:
class AgenciesController < ApplicationController
before_action :authenticate_user!
before_action :set_agency, only: [:show, :edit, :update]
# before_action :build_address, only: [:new, :edit]
def index
#agencies = Agency.all
end
def show
end
def create
#agency = Agency.new(agency_params)
respond_to do |format|
if #agency.save
format.html { redirect_to #agency, notice: 'Agency was successfully created.' }
format.json { render :show, status: :created, location: #agency }
else
format.html { render :new }
format.json { render json: #agency.errors, status: :unprocessable_entity }
end
end
end
def new
#agency = Agency.new
#agency.build_address
#agency.build_domain_name
#agency.branches.build
#agency.services.build
# #agency.branches.build_addresses
# #agency.branches.each do |branch|
# branch.build_address
# end
end
def edit
end
def update
respond_to do |format|
if #agency.update(agency_params)
format.html { redirect_to #agency, notice: 'Agency was successfully updated.' }
format.json { render :show, status: :ok, location: #agency }
else
format.html { render :edit }
format.json { render json: #agency.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_agency
#agency = Agency.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def agency_params
params.require(:agency).permit(:name, :logo, :description, :phone_number, :alt_phone_number, :email, :alt_email,
services_attributes:
[:id, :name, :description, :_destroy],
address_attributes:
[:id, :first_line, :second_line, :third_line, :city_town, :post_code, :_destroy],
domain_name_attributes:
[:id, :domain],
branches_attributes:
[:id, :name, :description, :phone_number, :alt_phone_number, :_destroy, :email, :alt_email,
services_attributes:
[:id, :name, :description, :_destroy],
address_attributes:
[:id, :first_line, :second_line, :third_line, :city_town, :post_code, :_destroy]
]
)
end
end
Apologies for the lengthy code.
The problem I was facing initially was that when I was adding a new branch, the address fields were not showing up. After some digging, I found a question on SO where someone suggested running f.object.build_address
just before calling the fields for the branch. This worked fine for creating a new branch on the agency form but after saving, and returning to the edit agency page, the address fields for the branch were blank. However, the address was saved correctly to teh database. I think this was caused bu the build_address line overriting the content when editing which is why I attempted to wrap it in the if loop but I'm almost certain this is wrong.
How can I correctly build the nested branch address attributes in the controller so that the fields are shown correctly when adding a new agency and or branch? And how can I ensure that the saved values are displayed correctly when I come back to edit the agency and branch(es) later.
I have done a lot of reading and digging and I cant see any of the normal issues like wrong tags used (<%= / <%) to no avail. Any help would be most appreciated.
Try with these modifications:
<%= f.fields_for #agency.address do |address| %>
<%= render 'addresses/address_fields', f: address %>
<% end %>
#other fields which all work fine
<div id="branches">
<%= f.fields_for #agency.branches do |branch| %>
<%= render 'branch_fields', f: branch %>
<% end %>
I have read these documents:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html
My source:
Model
app/models/product.rb
class Product < ActiveRecord::Base
has_many :product_items, foreign_key: :product_id, :dependent => :destroy
accepts_nested_attributes_for :product_items
end
app/models/product_item.rb
class ProductItem < ActiveRecord::Base
belongs_to :product
end
Controller
app/controllers/products_controller.rb
class ProductController < ApplicationController
def new
#product = Product.new
end
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to root_path }
else
format.html { render :new }
end
end
end
private
def product_params
params.require(:product).permit(:name, product_items_attributes: [ :description ])
end
end
View
app/views/products/_form.html.erb
<%= form_for(product, url: path) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :product_items do |item_form| %>
<%= item_form.label :description %>
<%= item_form.text_field :description %>
<% end %>
<%= f.submit 'Submit' %>
<% end %>
I can save the product data to the database, but it can't save product_items.
Edit
Add my post data after submit my form:
utf8:✓
authenticity_token:c5sdmoyLoN01Fxa55q6ahTQripx0GZvWU/d27C]asfdawofX9gw==
product[name]:apple
product[product_items][description]:good
commit:Submit
Edit 2
Add rails log:
Started POST "/products" for 10.0.2.2 at 2015-09-15 13:00:57 +0900
Processing by ProductController#create as HTML
I, [2015-09-15T13:00:58.039924 #28053] INFO -- : Parameters: {"utf8"=>"✓", "authenticity_token"=>"bilBzgOLc2/ZRUFhJORn+CJvCHkVJSsHQTg1V/roifoHxi9IRA==", "product"=>{"name"=>"apple", "product_items"=>{"description"=>"good"}}, "commit"=>"Submit"}
Your new method should like below in order to save product_items
def new
#product = Product.new
#product.product_items.build
end
You should also change your product_params like below for the update to work correctly in future.
def product_params
params.require(:product).permit(:name, product_items_attributes: [ :id, :description ])
end
Update your controller action product_params
def product_params
params.require(:product).permit(:name, product_items_attributes: [:id, :description, :_destroy ])
end
Either you can use nested_form gem which provide you complete demo and function control. Here is link https://github.com/ryanb/nested_form
When I press the submit button, it goes to my 'create' action and then saves the main object, but the foreign key is null as it has not been passed via post, here is my code:
Models:
class Ticket < ActiveRecord::Base
belongs_to :system
validates :title, presence: true, length: {minimum: 1, maximum: 60}
accepts_nested_attributes_for :system
end
class System < ActiveRecord::Base
has_many :tickets
validates :name, presence: true, length: {minimum: 1, maximum: 50}
end
Controller:
class TicketsController < ApplicationController
def new
#system = System.actives
#priority = Priority.actives
#ticket = Ticket.new
respond_to :js, :html
end
def create
#ticket = Ticket.new(ticket_params)
#ticket.save
respond_with(#ticket)
end
def ticket_params
params.require(:ticket).permit(:title, :active, systems_attributes: [:id,:name])
end
end
View
<%= form_for #ticket, remote: true do |f| %>
<div class="form-group">
<%= f.label :Título %><br>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :Sistema %><br>
<%= f.fields_for :systems do |fs| %>
<%= fs.collection_select :id,
#system.order(:name),:id,:name, {include_blank: 'Selecione...'},
{class: 'form-control', id: 'system_select'}%>
<% end %>
</div>
<div class="actions">
<%= f.submit "Abrir Chamado", class: "btn btn-info" %>
</div>
<% end %>
So, it saves the ticket object with a title, but without a system_id, any helpful tip would be great here.
There are few mistakes in your code.
Firstly,in your new action,you need to add this line #ticket.build_system
def new
#system = System.actives
#priority = Priority.actives
#ticket = Ticket.new
#ticket.build_system
respond_to :js, :html
end
Your ticket_params method should be like this
def ticket_params
params.require(:ticket).permit(:title, :active, system_id,system_attributes: [:id,:name])
end
Notice system_id and system_attributes.
And finally,you need to change this line <%= f.fields_for :systems do |fs| %> to <%= f.fields_for :system do |fs| %>
I don't entirely understand your form, but in ticket_params it looks like you have the :id you want in the array value for systems_attributes. If that is indeed what you're trying to pass your new Ticket, then it needs to be passed differently within Ticket.new. The arguments/options hash you're passing to Ticket.new with ticket_params should be key-value pairs like so:
Ticket.new(title: "yourtitle", other: "whatever", system_id: "your_id")
I'd either change the output of ticket_params so that it passes your system_id in this way, or manually pass it in (keying it out of the parameters) within your create action.
I am fairly new to Ruby on Rails and began with rails 4 right away.
I have sucessfully nested a Recipe and a Ingredient model so that they can be added in the same form. Next I want to nest quantity within ingredient so that that aswell can be added within the same form. Everything seems to be working fine up until when the quantity of the ingredient is about to be inserted in the database and from this i believe there is something wrong with the strong params in the recipes_controller. But i will post the full code below.
I am using simple_form for the forms.
Thankful for any help!
Here are my models:
class Recipe < ActiveRecord::Base
has_many :comments, dependent: :destroy
has_many :ingredients, dependent: :destroy
accepts_nested_attributes_for :ingredients, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
validates :title, presence: true
validates :desc, presence: true
end
class Ingredient < ActiveRecord::Base
belongs_to :recipe
has_many :quantities, dependent: :destroy
accepts_nested_attributes_for :quantities, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end
class Quantity < ActiveRecord::Base
belongs_to :ingredient
end
Here is the recipes_controller
class RecipesController < ApplicationController
def new
#recipe = Recipe.new
3.times do
ingredient = #recipe.ingredients.build
1.times {ingredient.quantities.build }
end
end
def create
#recipe = Recipe.new(params[:recipe].permit(:title, :desc, ingredients_attributes: [:id, :recipe_id, :name, :_destroy, quantities_attributes: [:id, :ingredient_id, :amount, :unit, :_destroy]]))
if #recipe.save
redirect_to #recipe
else
render "new"
end
end
def show
#recipe = Recipe.find(params[:id])
end
def edit
#recipe = Recipe.find(params[:id])
end
def update
#recipe = Recipe.find(params[:id])
if #recipe.update(params[:recipe].permit(:title, :desc))
redirect_to #recipe
else
render 'edit'
end
end
def destroy
#recipe = Recipe.find(params[:id])
#recipe.destroy
redirect_to recipes_path
end
def index
#recipes = Recipe.all
end
private
def post_params
params.require(:recipe).permit(:title, :desc, ingredients_attributes: [:id, :recipe_id, :name, :_destroy, quantities_attributes: [:id, :ingredient_id, :amount, :unit, :_destroy]])
end
end
Then i use simple form to create a form for recipe, ingredient and quantity through partials.
_form:
<%= simple_form_for #recipe do |f| %>
<%= f.error_notification %>
<%= f.input :title %>
<%= f.input :desc %>
<%= f.simple_fields_for :ingredients do |builder| %>
<%= render "ingredient_fields", :f => builder %>
<% end %>
<p class="links">
<%= link_to_add_association 'add ingredient', f, :ingredients %>
<p class="links">
<%= f.error :base%>
<%= f.submit %>
<% end %>
Which renders from _ingredients_fields:
<div class="nested-fields">
<%= f.input :name, label: "Ingredient" %>
<%= f.simple_fields_for :quantities do |builder| %>
<%= render "quantities_fields", :f => builder %>
<% end %>
<%= link_to_remove_association "remove", f %>
</div>
which renders from _quantities_fields: [EDITED]
<div class="nested-fields">
<%= f.input :amount %>
<%= f.input :unit %>
</div>
Trying to add new recipes result in the following log statement:
Started POST "/recipes" for 127.0.0.1 at 2013-10-29 14:15:40 +0100
Processing by RecipesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"t6LKgDLwAxaU9xo2ipyCM+j1yfVF9WrI8AoGTX+gRkw=", "recipe"=>{"title"=>"Pancakes", "desc"=>"Tasty", "ingredients_attributes"=>{"0"=>{"name"=>"Milk", "quantities_attributes"=>{"0"=>{"amount"=>"1", "unit"=>"Cup"}}, "_destroy"=>"false"}}}, "commit"=>"Create Recipe"}
[1m[35m (0.1ms)[0m begin transaction
[1m[36mSQL (3.5ms)[0m [1mINSERT INTO "recipes" ("created_at", "desc", "title", "updated_at") VALUES (?, ?, ?, ?)[0m [["created_at", Tue, 29 Oct 2013 13:15:40 UTC +00:00], ["desc", "Tasty"], ["title", "Pancakes"], ["updated_at", Tue, 29 Oct 2013 13:15:40 UTC +00:00]]
[1m[35mSQL (0.4ms)[0m INSERT INTO "ingredients" ("created_at", "name", "recipe_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Tue, 29 Oct 2013 13:15:40 UTC +00:00], ["name", "Milk"], ["recipe_id", 27], ["updated_at", Tue, 29 Oct 2013 13:15:40 UTC +00:00]]
[1m[36m (7.8ms)[0m [1mcommit transaction[0m
Redirected to http://www.projectcookbook.dev/recipes/27
Completed 302 Found in 22ms (ActiveRecord: 11.7ms)
You're using similar render for _quantities and _ingredients partials, which is wrong. In _quantities_field you don't need
<%= f.simple_fields_for :quantities do |builder| %>
<%= render "quantities_fields", :f => builder %>
<% end %>
AND should adjust
<%= f.input :name, label: "Quantity" %>
in _quantities_fields.
UPD
I think the problem is in :reject_if-clause at Ingredient model. It should be
:reject_if => lambda { |a| a[:amount].blank? }
bc here you specify conditions for Quantity, not for Ingredient
On code styling:
1) In controller it's better to use relevant name of private method for strong parameters: recipe_params instead of post_params and then use it for creation of new Recipe #recipe = Recipe.new(recipe_params)
2) Current associations between Recipe, Ingredient and Quantity will lead to Ingredient duplication in case two Recipes use similar one. The reason is belongs_to, which define single association. Try another approach (bellow).
BTW. recently I've answered on the similar question. Check it out: How do I reference an existing instance of a model in a nested Rails form?
I thing you are missing in this part
<%= simple_form_for #recipe do |f| %>
it should be
<%= simple_nested_form_for #recipe do |f| %>