nested attributes for registration form - ruby-on-rails

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

Related

Rails accepts nested attributes for multiple forms

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])

rails 4 has_one nested forms not building still

I have looked at all the posts about this fairly common problem on stackoverflow and elsewhere but I have not yet been able to find an answer. Essentially my nested form is not building, and is therefore not visible when I show the page.
Here is the relevant part of my user controller, users_controller.rb:
def new
#user = User.new
#user.build_user_account
end
Here is the relevant section from my user.rb file:
class User < ActiveRecord::Base
has_one :user_account, :class_name => "UserAccount"
accepts_nested_attributes_for :user_account
And my user_account.rb file:
class UserAccount < ActiveRecord::Base
belongs_to :user
end
Here is my _form.html.erb file:
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br>
<%= f.text_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br>
<%= f.text_field :password_confirmation %>
</div>
<% f.fields_for :user_account, #user.user_account do |user_account| %>
<div class="field">
<%= user_account.label :email %>
<%= user_account.text_field :email %>
</div>
<div class="field">
<%= user_account.label :password %>
<%= user_account.text_field :password %>
</div>
<div class="field">
<%= user_account.label :password_confirmation %>
<%= user_account.text_field :password_confirmation %>
</div>
<% end %>
the first three show up as expected, but the three form fields for user_account do not show up. I've tried everything that I could find online, but I still haven't been able to work out what the problem is - help would be appreciated!
I think you have just missed the = sign in the f.fields_for line. Try like this:
<%= f.fields_for :user_account, #user.user_account do |user_account| %>
The #user.user_account is not necessary either but does not harm.

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| %>

Embed devise form with extra field in different page

I'm using devise+omniaouth for authenticanton. My users also have a profile, with the following relationship;
class User < ActiveRecord::Base
has_many :authentications
has_one :profile
accepts_nested_attributes_for :profile
attr_accessible :email, :password, :password_confirmation, :remember_me, :profile_attributes
etc.
So my registrations/new.html.erb looks like this:
<% resource.build_profile %>
<%= form_for(resource, :as => resource_name,
:url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= f.fields_for :profile do |profile_form| %>
<h2><%= profile_form.label :name %></h2>
<p><%= profile_form.text_field :name %></p>
<% end %>
<h2><%= f.label :email %></h2>
<p><%= f.text_field :email %></p>
<h2><%= f.label :password %></h2>
<p><%= f.password_field :password %></p>
<h2><%= f.label :password_confirmation %></h2>
<p><%= f.password_field :password_confirmation %></p>
<p><%= f.submit "Sign up" %></p>
<br/>
<%= render :partial => "devise/shared/links" %>
<% end %>
<%= render "links" %>
As you can see, the only attribute that I'm trying to fill from the profile is 'name'. This works correctly and when you try to sign up from /users/sign_up, you have to fill name, email and password.
Now, I'm trying to display this registration window from a modal window, so I created:
/views/devise/menu/_registration_items.html.erb with the same info:
<%= form_for(resource, :as => resource_name,
:url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= f.fields_for :profile do |profile_form| %>
<h2><%= profile_form.label :name %></h2>
<p><%= profile_form.text_field :name %></p>
<% end %>
<h2><%= f.label :email %></h2>
<p><%= f.text_field :email %></p>
<h2><%= f.label :password %></h2>
<p><%= f.password_field :password %></p>
<h2><%= f.label :password_confirmation %></h2>
<p><%= f.password_field :password_confirmation %></p>
<p><%= f.submit "Sign up" %></p>
<br/>
<% end %>
I also added this to the application controller (it works the same way if I put it in the helper):
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
As explained at https://github.com/plataformatec/devise/wiki/How-To%3a-Display-a-custom-sign_in-form-anywhere-in-your-app
Everything works fine except that the name field doesn't dislpay in the form.(For example, the login form that doesn't have that field name works correctly). I guess that I have to map something else, but I don't know what it is.
Thanks!
I forgot to add the
<% resource.build_profile %>
line at the top of the form.

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