Validation always fails on all fields - ruby-on-rails

I'm on Rails 3. I have a model called Client that has name, phone and email. My model file looks like this:
class Client < ActiveRecord::Base
belongs_to :salon
belongs_to :address
validates_presence_of :name
validates_presence_of :phone
validates_presence_of :email
accepts_nested_attributes_for :address
attr_accessible :address_attributes
end
As you can see, name, phone and email are all required. When I go to the form where I'm supposed to be able to create a new Client and submit it, all three validations fail, no matter what I put in the fields. Here is my form file:
<%= form_for(#client) do |f| %>
<% if #client.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#client.errors.count, "error") %> prohibited this client from being saved:</h2>
<ul>
<% #client.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :salon_id, :value => Salon.logged_in_salon.id %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<%= f.fields_for :address do |address_form| %>
<div class="field">
<%= address_form.label :line1 %><br />
<%= address_form.text_field :line1 %>
</div>
<div class="field">
<%= address_form.label :line2 %><br />
<%= address_form.text_field :line2 %>
</div>
<div class="field">
<%= address_form.label :city %><br />
<%= address_form.text_field :city %>
</div>
<div class="field">
<%= address_form.label :state_id %><br />
<%= select("client[address]", "state_id", State.all.collect {|s| [ s.name, s.id ] }) %>
</div>
<div class="field">
<%= address_form.label :zip %><br />
<%= address_form.text_field :zip %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's my create action:
def create
#client = Client.new(params[:client])
respond_to do |format|
if #client.save
format.html { redirect_to(#client, :notice => 'Client was successfully created.') }
format.xml { render :xml => #client, :status => :created, :location => #client }
else
format.html { render :action => "new" }
format.xml { render :xml => #client.errors, :status => :unprocessable_entity }
end
end
end
Any idea why this is happening?

It's because you set :address_attributes as the only accessible attribute. Change
attr_accessible :address_attributes
to
attr_accessible :address_attributes, :name, :phone, :email
or don't use mass assignment.

Related

500 Internal Server Error when submitted a nested form in Rails

I get a 500 Internal Server Error when I submit the nested form which has two models - Member and ChildrenInformation.
Error:
500 Internal Server Error
If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.
I checked the log file, and this is what I found out:
TypeError (expected Hash (got Array) for param `child_info_attrib'):
Here are the other parts of my rails project
View (new.html.erb>
<%= form_for(#member) do |f| %>
<div class="field">
<%= f.label :gender, "Gender" %><br />
<%= f.select :gender, options_for_select(["Male", "Female"]) %>
</div>
<div class="field">
<%= f.label :fname, "First Name" %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :age, "Age" %><br />
<%= f.text_field :age %>
</div>
<div class="field">
<%= f.label :membership_id, "Membership ID" %>
<%= f.text_field :membership_id %>
</div>
<div class="field">
<%= f.label "Branch" %>
<%= f.collection_select(:branch_id, Branch.all, :id, :name) %>
</div>
<% for children_information in #member.children_informations %>
<%= fields_for "member[child_info_attrib][]", children_information do |children_info_form| %>
<div class="field">
<%= children_info_form.label :name, "Name" %><br />
<%= children_info_form.text_field :name %>
</div>
<div class="field">
<%= children_info_form.label :gender, "Gender" %><br />
<%= children_info_form.select :gender, options_for_select(["Male", "Female"]) %>
</div>
<div class="field">
<%= children_info_form.label :birthdate, "Birthdate" %><br />
nn <%= children_info_form.datetime_select :birthdate, :discard_hour => true,
:order => [:month, :day, :year], :start_year => 1900 %>
</div>
</div>
<% end %>
<% end %>`
Model (Member)
class Member < ActiveRecord::Base
has_many :children_informations
def child_info_attrib=(attribs)
attribs.each do |attrib|
children_informations.build(attrib)
end
end
end
Model (ChildrenInformation)
class ChildrenInformation < ActiveRecord::Base
belongs_to :member
end
Controller (MembersController)
class MembersController < ApplicationController
def new
#member = Member.new
#member.children_informations.build
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #member }
end
end
def create
#member = Member.new(params[:member])
respond_to do |format|
if #member.save
format.html { redirect_to(#member, :notice => 'Member was successfully created.') }
format.xml { render :xml => #member, :status => :created, :location => #member }
else
format.html { render :action => "new" }
format.xml { render :xml => #member.errors, :status => :unprocessable_entity }
end
end
end
Development Log: http://pastebin.com/n9E2nyFv (members table has a lot of fields)
What I tried so far is to omit the nested form, and it did work. Additionally, I based this way of using nested form through RailsCasts (http://railscasts.com/episodes/73-complex-forms-part-1).
How can I submit it successfully with the nested form?
Thank you in advance! :)
I think you're building your nested form incorrectly:
#app/views/members/new.html.erb
<% for children_information in #member.children_informations %>
<%= fields_for "member[child_info_attrib][]", children_information do |children_info_form| %>
<div class="field">
<%= children_info_form.label :name, "Name" %><br />
<%= children_info_form.text_field :name %>
</div>
<div class="field">
<%= children_info_form.label :gender, "Gender" %><br />
<%= children_info_form.select :gender, options_for_select(["Male", "Female"]) %>
</div>
<div class="field">
<%= children_info_form.label :birthdate, "Birthdate" %><br />
nn <%= children_info_form.datetime_select :birthdate, :discard_hour => true,
:order => [:month, :day, :year], :start_year => 1900 %>
</div>
</div>
<% end %>
<% end %>
You'd need to do this:
View
<%= f.fields_for :children_informations do |children_info_form| %>
<div class="field">
<%= children_info_form.label :name, "Name" %><br />
<%= children_info_form.text_field :name %>
</div>
<div class="field">
<%= children_info_form.label :gender, "Gender" %><br />
<%= children_info_form.select :gender, options_for_select(["Male", "Female"]) %>
</div>
<div class="field">
<%= children_info_form.label :birthdate, "Birthdate" %><br />
nn <%= children_info_form.datetime_select :birthdate, :discard_hour => true,
:order => [:month, :day, :year], :start_year => 1900 %>
</div>
</div>
<% end %>
This will create the form elements with the correct data, but I also think your handling of the data can be improved. As you're on Rails 3, I'll wait for a comment to see if you'd like me to write some code for it!
the railscast episode you are following is dated 2007.
I don't think this approach is the best in doing nested forms.
this
def child_info_attrib=(attribs)
attribs.each do |attrib|
children_informations.build(attrib)
end
end
could be simplified to this (if you are using rails 3.x >)
attr_accessible :childs_attributes
accepts_nested_attributes_for :childs
If you want references or some tutorials to follow I would recommend
http://railscasts.com/episodes/196-nested-model-form-revised
http://railscasts.com/episodes/197-nested-model-form-part-2
or if you don't those, you could look at this gem
https://github.com/nathanvda/cocoon
which simplifies what you are trying to achieve.
It was a mistake that I defaced the note of RailsCasts episode about nested forms (http://railscasts.com/episodes/73-complex-forms-part-1) that it is outdated, and I should instead follow the latest episode of the said topic (http://railscasts.com/episodes/196-nested-model-form-part-1). It worked now :)

Trouble about nested attributes form

This is my first question. I hope you can help me. I have two models.
class Cliente < ActiveRecord::Base
attr_accessible :cedula, :direccion, :nombres, :telefono
validates :cedula, :direccion, :nombres, :telefono, :presence => true
validates :cedula, :uniqueness => { :message => "Cedula ya en uso" }
has_many :facturas
class Factura < ActiveRecord::Base
attr_accessible :cliente_attributes, :iva, :numero, :subtotal, :total, :created_at
belongs_to :cliente
accepts_nested_attributes_for :cliente
I want in the facturas#new view can create or edit Cliente. If exists update or if not exists create. I am using nested attributes. If exists I uses javascript to fill text fields. If not exists I fill text field and save when Factura save. This is facturas#new view.
<h1>Nueva Factura</h1>
<%= form_for #factura do |f| %>
<% if #factura.errors.any? %>
<h2>Errores:</h2>
<ul>
<% #factura.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<p>
<div class = "contenedor_factura">
<%= f.label :numero %><br />
<%= f.number_field :numero %><br />
<%= f.label :fecha %><br />
<%= f.date_select :created_at %><br />
</div>
<div class = "contenedor_cliente">
<%= f.fields_for #cliente do |builder| %>
<%= builder.label :cedula, "Cédula" %>
<%= builder.text_field :cedula %>
<%= builder.label :nombres, "Nombres" %>
<%= builder.text_field :nombres %>
<%= builder.label :direccion, "Dirección" %><br />
<%= builder.text_field :direccion %>
<%= builder.label :telefono, "Teléfono" %><br />
<%= builder.text_field :telefono %>
<%= builder.hidden_field :id%>
<% end %>
</div>
<div class = "contenedor_productos">
</div>
<%= f.label :subtotal %><br />
<%= f.text_field :subtotal %>
<br />
<%= f.label :iva %><br />
<%= f.text_field :iva %>
</p>
<p>
<%= f.submit "Agregar Nueva Factura" %>
</p>
<% end %>
When the Cliente is new i have no problem, it saves, but if Cliente exists i have this message
ActiveRecord::RecordNotFound in FacturasController#create
Couldn't find Cliente with ID=6 for Factura with ID=
What is my problem?
EDIT:
This is my FacturasController
def new
#factura = Factura.new
#cliente = #factura.build_cliente
end
def create
#factura = Factura.new(params[:factura])
if #factura.save
redirect_to facturas_path, :notice => "Factura Guardada"
else
render "new"
end
end
I'm not sure if nested_attrubes handles already created models. So we can just not depend on it.
This should work
def create
cliente_attrs = params[:factura].delete :cliente
#cliente = cliente_attrs[:id].present? ? Cliente.find(cliente_attrs[:id]) : User.create(user_attrs)
#factura = cliente.facturas.build(params[:factura])
if #factura.save
redirect_to facturas_path, :notice => "Factura Guardada"
else
render "new"
end
end
You can now delete the line accepts_nested_attributes_for :cliente

Nested Form Error - ArgumentError (wrong number of arguments (0 for 1)):

I followed this screencast to make a nested model form.
http://railscasts.com/episodes/196-nested-model-form-part-1
Now, I am trying my application to include such a nested model form but I received a argument error (wrong number of arguments(0 for 1)).
I can't seem to figure out where I went wrong and would like to seek some advice on what I could try out and why some an error might have occurred.
The error happens on this line in the Subject Model.
has_many :lessons, :dependent => destroy
The other relevant codes:
Subjects Controller:
def new
#subject = Subject.new
#3 times one for lecture one for lab one for tut.
3.times{#subject.lessons.build}
respond_to do |format|
format.html # new.html.erb
format.json { render json: #subject }
format.js
end
end
Subject Model
class Subject < ActiveRecord::Base
has_many :lessons, :dependent => destroy
attr_accessible :lesson_attributes, :acad_unit, :cohort_size, :discipline, :remarks, :subject_code, :subject_name, :year_of_study
accepts_nested_attributes_for :lessons, :reject_if => lambda { |a| a[:lesson_type].blank? }, :allow_destroy => true
end
Lesson Model
class Lesson < ActiveRecord::Base
belongs_to :subject
attr_accessible :frequency, :lesson_type, :no_of_lesson, :possible_venues
end
_form.html.erb
<%= form_for(#subject,:remote=>true) do |f| %>
<% if #subject.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#subject.errors.count, "error") %> prohibited this subject from being saved:</h2>
<ul>
<% #subject.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :subject_code %><br />
<%= f.text_field :subject_code %>
</div>
<div class="field">
<%= f.label :subject_name %><br />
<%= f.text_field :subject_name %>
</div>
<div class="field">
<%= f.label :year_of_study %><br />
<%= f.text_field :year_of_study %>
</div>
<div class="field">
<%= f.label :discipline %><br />
<%= f.text_field :discipline %>
</div>
<div class="field">
<%= f.label :acad_unit %><br />
<%= f.text_field :acad_unit %>
</div>
<div class="field">
<%= f.label :cohort_size %><br />
<%= f.text_field :cohort_size %>
</div>
<div class="field">
<%= f.label :remarks %><br />
<%= f.text_field :remarks %>
</div>
<ol>
<%= f.fields_for :lessons do |builder| %>
<%= render "lesson_fields", :f => builder %>
<% end %>
</ol>
<% end %>
_lesson_fields.html.erb
<p>
<div class="field">
<%= f.label :lesson_type %><br />
<%= f.text_field :lesson_type %>
</div>
<div class="field">
<%= f.label :no_of_lesson %><br />
<%= f.text_field :no_of_lesson %>
</div>
<div class="field">
<%= f.label :frequency %><br />
<%= f.text_field :frequency %>
</div>
<div class="field">
<%= f.label :possible_venues %><br />
<%= f.text_field :possible_venues %>
</div>
</p>
I guess you wanted :
has_many :lessons, :dependent => :destroy
?
Here you'll find a nice discussion on topic.

has_many record insertion

I want to insert tags in new Place. giving that tags is in different model.
####### models ##########
class Tag < ActiveRecord::Base
belongs_to :place
attr_accessible :tag
end
class Place < ActiveRecord::Base
has_many :tags
end
how can I handle this in the new Place create form? and the create action in the places_controller? so that I can insert new place and mant tags then assign the product id to each tag.
####### place controller ##########
def create
#place = Place.new(params[:place])
#tag = Tag.new(params[:?????]) #this should be more than once
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render json: #place, status: :created, location: #place }
else
format.html { render action: "new" }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
####### place new form ##########
<%= form_for #place do |f| %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :rank %><br />
<%= f.text_field :rank %>
</div>
<div class="field">
<%= f.label :lat %><br />
<%= f.text_field :lat %>
</div><div class="field">
<%= f.label :lng %><br />
<%= f.text_field :lng %>
</div>
<div class="field">
<%= f.label :address %><br />
<%= f.text_area :address %>
</div>
<div class="field">
<%= f.label :website %><br />
<%= f.text_field :website %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<div class="field">
<%= label_tag "tags" %>
<%= f.text_field :tag %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
If you want to do it on your own, you should look into accepts_nested_attributes_for, where there's a great 2 part tutorial by Ryan Bates at railscasts.com
If you don't want to do it on your own, there are several tag gems available, for instance:
ActsAsTaggableOn.
Add this in your form:
<%= f.fields_for :tags do |t| %>
<%= t.label :name %>
<%= t.text_field :name %>
<% end %>
And in your Place model:
accepts_nested_attributes_for :tags
And in your controller, you wouldn't even have to worry about creating tags.
You should still try to read about fields_for and accepts_nested_attributes_for, they're often useful, since your problem is very common.

Ruby On Rails Form with integers titles instead of numbers in a drop-select-list

Hi
I'm pretty new with Ruby On Rails, and came across this problem.
I have 4 tables, and 1 that has the three others connected to it.
Sportcategories - name of each category
Sports - Name of each sport
Clubs - Name of each club
Results,
t.integer "sportcategory_id"
t.integer "sport_id"
t.integer "club_id"
I have managed to make a simple edit form with text_field for each field in results. But how can I get the names for the integers instead of the numbers?
<%= form_for(#result) do |f| %>
#if...
#..
#end
<div class="field">
<%= f.label :sportcategory_id%><br />
<%= f.text_field :sportcategory_id%>
</div>
<div class="field">
<%= f.label :sport_id %><br />
<%= f.text_field :sport_id %>
</div>
<div class="field">
<%= f.label :club_id %><br />
<%= f.text_field :club_id %>
</div>
<div class="field">
<%= f.label :result %><br />
<%= f.text_field :result %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I have made it so that SportCat, Sports and clubs has many results and that results belongs to all of them.
This is my controller file for results with edit & update
def edit
#result = Price.find(params[:id])
end
def update
#price = Price.find(params[:id])
respond_to do |format|
if #price.update_attributes(params[:price])
format.html { redirect_to(#price, :notice => 'Price was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #price.errors, :status => :unprocessable_entity }
end
end
end
And question two might be answered in question one, but I want to be able to choose from a drop-down list from all the available categories, sports and clubs with their actual name and then pass the right ID when I update it.
Check the Rails Form select helper
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
<%= form_for(#result) do |f| %>
<div class="field">
<%= f.label :sportcategory_id%><br />
<%= f.select :sportcategory_id, #sportcategories.map {|s| [s.name, s.id]} %>
</div>
<div class="field">
<%= f.label :sport_id %><br />
<%= f.select :sport_id, #sports.map {|s| [s.name, s.id]} %>
</div>
<div class="field">
<%= f.label :club_id %><br />
<%= f.select :club_id, #clubs.map {|c| [c.name, c.id]} %>
</div>
<div class="field">
<%= f.label :result %><br />
<%= f.text_field :result %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Get #sportcategories, #sports, #clubs in your controller actions.

Resources