Rails accepts nested attributes for multiple forms - ruby-on-rails

I have two models, parent and child. I want, while i am creating parent using form, to create children for him. I have following:
parent.rb
class Parent < ActiveRecord::Base
has_many :children
accepts_nested_attributes_for :children
end
child.rb
class Child < ActiveRecord::Base
belongs_to :parent
end
_form.rb
<%= form_for Parent.new do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %></br>
<%= f.label :last_name %>
<%= f.text_field :last_name %></br>
<%= f.label :email %>
<%= f.text_field :email %></br>
<%= f.label :phone %>
<%= f.text_field :phone %></br>
<%= f.fields_for Child.new do |builder| %>
<%= builder.label :first_name %><br>
<%= builder.text_field :first_name %><br>
<% end %>
<%= f.fields_for Child.new do |builder| %>
<%= builder.label :first_name %><br>
<%= builder.text_field :first_name %><br>
<% end %>
<%= f.submit %>
<% end %>
I want to be able, while i am creating parent, to create one or multiple children for him. If i submit this form, i get message Unpermitted parameter: child.
Also in my params hash, when i submit this form, i get only info for child in last child form. How to fix this?
This is my params permit method :
params.require(:parent).permit(:first_name, :last_name, :email, :phone, child:{})

You are permitting children attributes in a wrong ways, Please use this :
params.require(:parent).permit(:first_name, :last_name, :email, :phone, children_attributes: [:first_name])

Related

Unable to get fields for a nested model form for a has_one relationship to show on the new view in Rails 4.0

I have a BikeShops model:
class BikeShop < ActiveRecord::Base
has_one :user, :as => :profile, :dependent => :destroy
accepts_nested_attributes_for :user
end
And a Users model:
class User < ActiveRecord::Base
belongs_to :profile, :polymorphic => true
end
I am trying to create a nested form in the bike_shops/new view. Here is the code I have: in there:
<%= form_for(#bike_shop) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, 'Shop Name' %>
<%= f.text_field :name %>
<%= f.label :street_address, 'Street Address' %>
<%= f.text_field :street_address %>
<%= f.label :city, 'City' %>
<%= f.text_field :city %>
<%= f.label :state, 'State' %>
<%= f.text_field :state %>
<%= f.label :zip_code, 'Zip Code' %>
<%= f.text_field :zip_code %>
<%= f.label :phone_number, 'Phone Number' %>
<%= f.text_field :phone_number %>
<%= f.label :website, 'Website' %>
<%= f.text_field :website %>
<% f.fields_for(:user) do |builder| %>
<%= builder.label :first_name, 'First Name:' %>
<%= builder.text_field :first_name %>
<%= builder.label :last_name, 'Last Name:' %>
<%= builder.text_field :last_name %>
<%= builder.label :email, 'Email:' %>
<%= builder.text_field :email %>
<%= builder.label :password, 'Password:' %>
<%= builder.password_field :password %>
<%= builder.label :password_confirmation, 'Password Confirmation:' %>
<%= builder.password_field :password_confirmation %>
<% end %>
<%= f.submit "Signup My Bike Shop", class: "btn btn-large btn-primary" %>
<% end %>
The fields for #bike_shop appear but the nested fields for the has_one #user do not appear. Here is the code in the BikeShops controller:
class BikeShopsController < ApplicationController
def new
#bike_shop = BikeShop.new
#user = #bike_shop.build_user
end
I was following this railscast but can't get pass getting the fields for the nested form to show. Any help is appreciated.
You need to use the <%= erb tag in order to render it instead of just <%
<%= f.fields_for(:user) do |builder| %>

How to display data from two tables into one form

I use Ruby v 3. I want to display data from 2 tables into one form.
My models:
class Address < ActiveRecord::Base
attr_accessible :city, :number, :street
validates :city, :presence => true
validates :number, :presence => true
validates :street, :presence => true
has_many :users
end
class User < ActiveRecord::Base
belongs_to :address
attr_accessible :name, :phone, :surname, :address_attributes
accepts_nested_attributes_for :address
end
My form looks alike:
<%= form_for(#user) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :surname %><br />
<%= f.text_field :surname %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<%= f.fields_for :address_attributes do |p| %>
<div class="field">
<%= p.label :city %><br />
<%= p.text_field :city %>
</div>
<div class="field">
<%= p.label :street %><br />
<%= p.text_field :street %>
</div>
<div class="field">
<%= p.label :number %><br />
<%= p.text_field :number %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
As you can see I use fields_for method. And my controller is here:
def edit
#user = User.find(params[:id])
#user.address_attributes = #user.address
end
It does not working and I totally don't know why. When I click edit on address list i've got an error:
undefined method `with_indifferent_access'
Anyone can help me figure it out?
Check out Episodes 196 and 197 on RailsCasts:
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
There is a revised episode for 196, for which you will need to subscribe to RailsCasts.
I would highly recommend subscribing to learning sites like RailsCasts and CodeSchool, to lear RoR faster and in the right way.
Try to do:
def edit
#user = User.find(parmas[:id])
end
and on your view:
<%= f.fields_for :address do |p| %>
and see if it works, you don't have to add the attributes

Create checkbox array in form_for rails

I have this _form file.
<%= form_for(#company) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :company_type %>
<%= f.select :company_type_id, CompanyType.order(:name).map{|x| [x.name, x.id]} %>
<%= f.label :description %>
<%= f.text_area :description %>
<%= f.submit %>
<% end %>
My question is how do I change select
<%= f.select :company_type_id, CompanyType.order(:name).map{|x| [x.name, x.id]} %>
in this form into checkbox list?
CompanyType model:
class CompanyType < ActiveRecord::Base
attr_accessible :name
has_many :companies
end
Company model:
class Company < ActiveRecord::Base
attr_accessible :description, :name, :company_type_id, :website
belongs_to :type, :class_name => "CompanyType", :foreign_key => :company_type_id
end
Try this
<%= f.check_box :company_type_id, CompanyType.order(:name).map{|x| [x.name, x.id]} %>
Try the checkboxes_select method
http://edgeapi.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes

nested attributes for registration form

I have a user and a company model where a user has_one company and company belongs to user. I just wanted to save the company field from the registration form to the company table,where the company table columns are user_id and company_name. I used the following to do this in my User.rb
has_one :company, :class_name => 'Company', :foreign_key => :user_id, :dependent => :destroy
accepts_nested_attributes_for :company
And My registration form looks like this
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<p><%= f.label :firstname %><br/>
<%= f.text_field :firstname %></p>
<p><%= f.label :lastname %><br/>
<%= f.text_field :lastname %></p>
<p><%= f.label :email %><br/>
<%= f.email_field :email %></p>
<p><%= f.label :password %><br/>
<%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %><br/>
<%= f.password_field :password_confirmation %></p>
<%= fields_for :company do |builder| %>
<%= builder.label :company %>
<td><%= builder.text_field :company_name%> </td>
<% end %>
<p><%= f.submit "Sign up" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>
Is it necessary to have a hidden field for user_id for company table or it will get automatically added, I also tried overriding the create method of registration controller it works but the devise error messages are not working. Can anyone help me out in this. I dont know what I have missed. Thanks in advance.
1) No, you don't need a user_id hidden field, just use fields_for as a method
<%= f.fields_for :company do |builder| %>
...
<% end %>
2) fields_for will not be shown if user does not have associated companies yet, and that will happen with new record, so you can do
<% f.object.company.build %> as a hack :)
or do it the proper way in a controller action

Rails way to set up relationship for this model

Being new at Ruby and Rails, I wasn't sure how to explain this in my title so i will do it here. My goal is to create many Products and with those have only one overall Location per submit.
I have a Product MVC and a quick ugly sketch of the form would be something like this:
Overall Location
form_for #product
<p>
<%= f.label :location %>:<br>
<%= f.text_field :location %>
</p>
Product one
<p>
<%= f.label :name %>:<br>
<%= f.text_field :name %>
<%= f.label :price %>:<br>
<%= f.text_field :price %>
</p>
Product Two (same)
<p>
<%= f.label :name %>:<br>
<%= f.text_field :name %>
<%= f.label :price %>:<br>
<%= f.text_field :price %>
</p>
Product Three(same)
<p>
<%= f.label :name %>:<br>
<%= f.text_field :name %>
<%= f.label :price %>:<br>
<%= f.text_field :price %>
</p>
<%= f.submit %>
<% end %>
How would you set it up so this relationship could take place so when a user creates 3 products on a form, he has only one location for all 3 of them?
This way:
class Location < AR::Base
has_many :products
end
class Product < AR::Base
belongs_to :location
end
You'd then set up a nested resource route:
resources :locations do
resources :products
end
And when you're adding a location, you can add products to it with fields_for.
is it required to use nested_attributes_for in this scenario..

Resources