I'm really new at Ruby On Rails and I'm working with a baseApp that comes with the login and user registration functionalities. It also creates an empty profile for a user when they sign up.
Then, I've created a migration to add fields to the profiles table, such as firstName, gender, state, country, etc.
What I'd like to do, is to show those fields at the registration form and then save them on the profiles table. How can I do this?
Thanks,
Brian
accepts_nested_attributes_for provides everything you need.
So long as you've st up your user to have one profile you're just about good to go.
Add accepts_nested_attributes_for :profile to the User model. Then set up your form to be something like this:
<% form_for :user do |f| %>
...
User model fields
...
<% #user.build_profile if #user.profile.nil? %>
<% f.fields_for :profile do |p| %>
<%= p.label :first_name %>
<%= p.text_field :first_name %>
...
Profile model fields
...
<% end %>
<% end %>
The controller needs no modification.
Read up on the nested form section of FormHelper for more details.
Related
I have an ordinary form to create a Package object at /packages/new:
<%= form_for #package do |f| %>
<%= f.text_field :name %>
<%= f.text_field :address %>
...
<% end %>
The package model belongs_to :partner.
I am looking for a way to associate a new package form to a specific partner, preferably without any input from the user filling it in.
For example, if partner A sends a link to the form, I want the form to include partner_id:A.id.
How can I connect forms to partners?
You can send partner_id param with the link which your partner will send.
Something like
http://website.com/packages/new?partner_id=3
And use the param as hidden_field in the form
<%= form_for #package do |f| %>
<%= f.text_field :name %>
<%= f.text_field :address %>
<%= f.hidden_field :partner_id, value: params[:partner_id] %>
...
<% end %>
Alternatively you can also make use of Nested Resources
you can have, hidden field which passes partner_id to controller
http://apidock.com/rails/ActionView/Helpers/FormHelper/hidden_field
If the partner needs to be logged in, in order to create a package, you could simply link the package to the partner in the controller right before saving it.
As mentioned before, use params. And don't forget to allow the required params in the controller if necessary (via link, scroll down a little). documentation: params
Check out what e.g. .build() does for you. more about relations and how to set them up correctly
I'm trying to implement a quote saving feature in a Rails app. I have a User Model that has_many :quotes and a Quote Model that belongs_to :user. Now I have a separate Book Model that would be the source of these quotes.
Within the Book's show.html.erb file, I have a form to save quotes for the current user
<%= form_for (#new_quote) do |f| %>
<div class="field">
<%= f.hidden_field :book_id, :value => #new_comment.book_id %>
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And in the Book controller, I have
def show
#new_quote = current_user.quotes.create(book_id: params[:id])
end
The quote saves fine but the problem is, since I have this Quote creation statement in the show method, everytime I go to the show.html.erb page of my Book model, it creates a Quote with an empty body.
What can I do to solve this? I was thinking it probably would involve moving this Quote creation to the actual create method of the Quote controller but I don't know how to exactly pass the parameters through.
You could just build that quote, but not save it to the database. Then the user need to send the form to save that record. Just change your show method to:
def show
#new_quote = current_user.quotes.build(book_id: params[:id])
end
I am working on a rails form. Essentially, a person can have multiple statuses and switch between the different statuses. In database table, the display will be simple as follows:
status start_date end_date
work 1/1/15 1/10/15
sick 1/11/15 2/15/15
work 2/16/15 3/15/15
sick 1/15/15 1/14/15
I need to prompt user to input these information. I have made a status class which belongs to a person class. So basically, these fields will be a part of nested forms.
My question is: How can I dynamically display these information to make forms elegant and clean to use?
Thanks!
If I understood your domain, your Person has many Status, right?
The simplest way to do it is use the gem cocoon. Your view will look like this:
<%= form_for #person do |person_form| %>
<%= person_form.input :name %>
<%= person_form.fields_for :statuses do |status_form| %>
<%= status_form.field :start_date, :end_date %>
<!-- cocoon's method to dynamically add nested forms -->
<%= link_to_add_association 'add status', person_form, :statuses
<% end %>
<% end %>
I have a User controller that possesses the two following records:
user.vehicles from VehiclesController
user.trip_distances from TripDistancesController
In the Vehicles view, I need to display and update both models (Vehicle and TripDistance)
I figured out that I need to use a nested form. However, I don't understand how to implement it since my #trip_distances record needs a loop in order to display all of its content.
First, I tried to put this in the Vehicle model, but since both are NOT linked, I wonder if this is correct:
accepts_nested_attributes_for :trip_distances, allow_destroy: true
Then, in the Vehicle view's _form file, during the edit action, I have:
<%= form_for(#vehicle) do |f| %>
I need to put my nested form inside it. Here's what I got so far:
<% #trip_distances.each do |t| %>
<%= f.fields_for t do |fields| %>
<div class="field">
<%= fields.text_field :id_contract %>
<%= fields.number_field :length %>
</div>
<% end %>
<% end -%>
My trip_distances records are correctly displayed, but the unique Submit button doesn't work anymore. I'd like to update both model while clicking on one button. What am I missing?
I was able to make it work by associating the two models. Then I use the following fields_for tag:
<%= f.fields_for :trip_distances do |builder| %>
My submit button is now working, but the :trip_distances fields are not updated, I don't know why.
I have a user and a profile model. One user can have many profiles. I need to access only one information from the profiles section (viz the phone number) in my user model during the user creation process. Hence I'm trying to get it done through attr_accessible. My user.rb looks like this.
has_many :profiles
attr_accessible :handle, :email, :password, :profile_mobile_number
attr_accessor : :profile_mobile_number
The problem that I'm facing is that when I try to call the getter method profile_mobile_number in a method in user.rb (the method is private, though I think it doesn't matter), I'm getting a null value. I use the following in my users/new.html.erb form
My question is what is the right way to do this? Should I use <% f.fields_for :profile do |ff| -%> or <% f.fields_for :profiles do |ff| -%> (notice that the second one is plural). When I use the plural :profiles, I don't even see the fields on the form. What am I missing here? And what is the tense that needs to be used in model user.rb? :profile_phone_number or :profiles_phone_number? Thanks.
You could do something like the following:
<% form_for #user, :url => { :action => "update" } do |user_form| %>
...
<% user_form.fields_for :profiles do |profiles_fields| %>
Phone Number: <%= profiles_fields.text_field :profile_mobile_number %>
<% end %>
<% end %>
But since you already have an association, then might as well use 'accepts_nested_attributes_for'
You should watch RailsCasts Nested Model Form.
thanks Ryan Bates great work.
http://apidock.com/rails/v3.2.8/ActionView/Helpers/FormHelper/fields_for
This api dock link list many Nested Attributes Examples including one-to-one, one-to-many. It's very helpful!
You can use 'accepts_nested_attributes_for' to do this; but there's a little trick in forms:
You must use the singular, and call fields_for for each profile, like this:
<% form_for #user do |f| -%>
<% #user.profiles.each do %>
<% f.fields_for :profile_attributes, profile do |ff| -%>
<% end %>
Notice that is :profile_attributes, instead of just :profile.