Rails 3.1 RC4
I have a 1:1 association between User and Profile.
When I submit the new profile form, the data I've entered is displayed just fine (see screenshot: http://i.imgur.com/fY8YU.png), but when I refresh it the data is instantly wiped.
Could anyone tell me what is causing this?
Here's the submit form:
<%= form_for([#user, #user.build_profile]) do |f| %>
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :picture %><br />
<%= f.text_field :picture %>
</div>
<div class="field">
<%= f.radio_button(:sex, "male") %>
<%= f.label(:sex, "Male") %>
<%= f.radio_button(:sex, "female") %>
<%= f.label(:sex, "Female") %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's the users_controller: https://github.com/imjp/SuperModel/blob/master/app/controllers/users_controller.rb
Here's the profiles_controller: https://github.com/imjp/SuperModel/blob/master/app/controllers/profiles_controller.rb
I'm not sure I agree with your approach. Why don't you do something like this:
In models/user.rb:
accepts_nested_attributes_for :profile
In controllers/users_controller.rb:
def new
#user = User.new
#user.build_profile
end
In views/users/_form.html.erb:
<%= form_for #user do |f| %>
<%= f.text_field :first_name %>
<%= f.fields_for :profile do |pf| %>
<%= pf.text_field :some_profile_field %>
<% end -%>
<%- end -%>
This isn't copied or tested, but it should work. On saving your user, the profile fields are sent along and validated with the user fields and are re-rendered when rendering the form again after a save error. This way you will keep full control over your form and its contents with minimal effort.
Related
New to rails and getting confused on how to handle this. I am using rails 4. I am very stuck here and will try to talk through this problem.
I have a listings page which I am trying to add tags too. In my view (listings/new.html.erb) I have the following:
<h1> POST A NEW LISTING </h>
<% if current_user.nil? %>
<h2>You must be logged in to view this page </h2>
<% else %>
<%= form_for [#user, #listing] do |f| %>
<%= f.label :title, 'Title' %> <br />
<%= f.text_field :title %>
<%= f.label :general_info, 'General Information' %> <br />
<%= f.text_area :general_info %>
<%= f.label :included, 'Included' %> <br />
<%= f.text_field :included %>
<%= f.label :length, 'Length' %> <br />
<%= f.text_field :length %>
<%= f.label :price, 'Price' %> <br />
<%= f.text_field :price %>
<% fields_for #tagging do |u| %>
<%= u.label :tag, 'Tag' %> <br />
<%= u.text_field :tag %>
<% end %>
<%= f.submit "submit" %>
<% end %>
<% end %>
The form works correctly for putting in the listing, but the tagging form options do not even appear to allow for content.
my listings_conroller #new looks like this:
def new
if (!current_user.nil?)
#user = User.find(current_user.id)
#listing = #user.listings.build
#tagging = #listing.taggings.build
end
end
I want to be able to create a new listing with this form that also populates the database for the tags and I am very unsure on how to do this. I hope this is enough information, but if needed I have all the code here: https://bitbucket.org/r-s/ath/src . Very stuck on this any help would be appreciated.
Change it to:
<%= f.fields_for #tagging do |u| %>
Note the =.
You forgot to use builder:
<%= f.fields_for #tagging do |u| %>
I'm working on a advanced search form. I am working in views/searches. Now I have attributes created for user profiles that I have been using such as zip code, age, gender, career, religion, education, etc. I want to use these fields for my advanced search.
When I include the f.label and text fields I get a undefined method. I'm hoping I don't have to recreate each attribute for the search form, as that would not make much sense considering I have already done all these attributes for the user profile. Any help would be greatly appreciated!
/searches/new.html (for search):
<%= form_for #search do |f| %>
<div class="field">
<%= f.label :keywords %><br/>
<%= f.text_field :keywords%>
</div>
<div class="field">
<%= f.label :zip_code %><br/>
<%= f.text_field :zip_code %>
</div>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
/users/new.html (for the user profile):
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br/>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br/>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :username %><br/>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :zip_code %><br/>
<%= f.text_field :zip_code %>
</div>
</div>
<div class="field">I'm a
<%= f.select :gender, ['man', 'woman']%>
interested in
<%= f.select :gender, ['women', 'men', 'both']%>
</div>
<div class="field">
Age <%= select(#object, :age, (18..75).to_a) %> to <%= select(#object, :age, (18..75).to_a) %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
Your #search object is a Search object (or whatever it actually is), not a User.
Rails doesn't know your Search object doesn't actually have those fields, so when it tries to retrieve the fields that don't exist, it'll blow up.
There are any number of ways around this, including giving your Search a User property.
You could also create a new User and pass it to a user form partial as f, that's probably the approach I would take, although I don't know precisely what it would look like without trying it.
I have a form that I copied over from new.html.erb and put it in edit.html.erb. I essentially want the same form, but if there are values already in the database for the form fields I want them to be pulled into the form for editing. I currently have something like this:
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
.
.
.
.
<div class="actions"><%= f.submit %></div>
<% end %>
How can I pull from the the database to fill in the fields with appropriate values?
This will happen automatically if you set #user in the 'edit' action of your controller - something like
def edit
#user = User.find(params[:id])
end
you might also think about including the form as a partial rather than repeating it to DRY up your code - this link gives the general idea
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Associated model is not saving data when page is refreshed
I have a 1:1 association between User and Profile.
When I submit the new profile form, the data I've entered is displayed just fine (see screenshot: http://i.imgur.com/fY8YU.png), but when I refresh it the data is instantly wiped.
Could anyone tell me what is causing this?
Here's the submit form:
<%= form_for([#user, #user.build_profile]) do |f| %>
<div
class="field"> <%= f.label :first_name %><br /> <%=
f.text_field :first_name %> </div> <div
class="field"> <%= f.label :last_name %><br /> <%=
f.text_field :last_name %> </div> <div
class="field"> <%= f.label :picture %><br /> <%=
f.text_field :picture %> </div> <div class="field">
<%= f.radio_button(:sex, "male") %> <%=
f.label(:sex, "Male") %> <%= f.radio_button(:sex, "female")
%> <%= f.label(:sex, "Female") %> </div> <div
class="actions"> <%= f.submit %> </div> <%
end %>
Here's the users_controller: https://github.com/imjp/SuperModel/blob/master/app/controllers/users_controller.rb
Here's the profiles_controller: https://github.com/imjp/SuperModel/blob/master/app/controllers/profiles_controller.rb
Basically, it's failing because:
passing #user.build_profile instantiates a new profile each time.
sidenote but I highly recommend you create the profile just after the user is created.
Look at my commit on your forked repository.
I have a Person model and an Address Model:
class Person < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
belongs_to :person
end
In my people controller I have #person.build_address in my new action. My forms builds correctly. The problem is that when I submit the form, a person record and an address record is created but they aren't linked via the address_id column in the Person table.
Am I missing a step in the controller?
Thanks!
New Action
UPDATE
def new
#person = Person.new
#person.build_address
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #person }
end
end
Form Code
UPDATE
<%= form_for(#person) do |f| %>
<% if #person.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#person.errors.count, "error") %> prohibited this person from being saved:</h2>
<ul>
<% #person.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :telephone %><br />
<%= f.text_field :telephone %>
</div>
<div class="field">
<%= f.label :mobile_phone %><br />
<%= f.text_field :mobile_phone %>
</div>
<div class="field">
<%= f.label :date_of_birth %><br />
<%= f.date_select :date_of_birth %>
</div>
<div class="field">
<%= f.label :gender %><br />
<%= f.select(:gender, Person::GENDER_TYPES) %>
</div>
<div class="field">
<%= f.label :notes %><br />
<%= f.text_area :notes %>
</div>
<div class="field">
<%= f.label :person_type %><br />
<%= f.select(:person_type, Person::PERSON_TYPES) %>
</div>
<%= f.fields_for :address do |address_fields| %>
<div class="field">
<%= address_fields.label :street_1 %><br />
<%= address_fields.text_field :street_1 %>
</div>
<div class="field">
<%= address_fields.label :street_2 %><br />
<%= address_fields.text_field :street_2 %>
</div>
<div class="field">
<%= address_fields.label :city %><br />
<%= address_fields.text_field :city %>
</div>
<div class="field">
<%= address_fields.label :state %><br />
<%= address_fields.select(:state, Address::STATES) %>
</div>
<div class="field">
<%= address_fields.label :zip_code %><br />
<%= address_fields.text_field :zip_code %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You need to have accepts_nested_attributes_for :address on your Person model for this to work nicely. In your create action you can then do this:
def create
#person = Person.new(params[:person])
...
end
Then Rails will take care of the rest.
UPDATE: if the address_id column is in the people table then it should be belongs_to :address, not has_one :address
Why is your address built in your new action, and not in the create action? You're building an address from a non saved model, without an id, so the foreign key can't be set. You should keep your #person in your new action, but put your build_address in your create action, after #person has been saved.