Hello:
I am quite new to Ruby and Rails. Here are the details of a sample use
case that I am trying to build.
Development environment: (on Ubuntu 9.04)
##################################
Ruby version 1.8.7 (i486-linux)
RubyGems version 1.3.1
Rails version 2.1.0
Active Record version 2.1.0
Action Pack version 2.1.0
Active Resource version 2.1.0
Action Mailer version 2.1.0
Active Support version 2.1.0
Edge Rails revision unknown
Application root /home/vkottilil/myapp
Environment development
Database adapter sqlite3
Database schema version 20091120203804
Sample Application:
################
User and Address maintenance - a bunch of user data with addresses
Model:
######
class User < ActiveRecord::Base
has_one :address
validates_presence_of :first_name, :last_name
end
class Address < ActiveRecord::Base
belongs_to :user
end
Controller:
########
users_controller.rb (new and create blocks)
def new
@user = User.new
@address = Address.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @user }
end
end
def create
@user = User.new(params[:user]) ## --> line 45
@address = @user.address.build(params[:address])
respond_to do |format|
if @user.save
flash[:notice] = ''User was successfully created.''
format.html { redirect_to(@user) }
format.xml { render :xml => @user, :status
=> :created, :location => @user }
else
format.html { render :action => "new" }
format.xml { render :xml => @user.errors, :status
=> :unprocessable_entity }
end
end
end
The view comes up with out errors (http://localhost:3000/users/new)
and when I click on create this error is generated.
ActiveRecord::AssociationTypeMismatch in UsersController#create
Address(#-615658568) expected, got HashWithIndifferentAccess
(#-606879698)
RAILS_ROOT: /home/vkottilil/myapp
stack dump ---
-----
app/controllers/users_controller.rb:45:in `new''
app/controllers/users_controller.rb:45:in `create''
----
-------
Request Parameters:
{"commit"=>"Create",
"authenticity_token"=>"1459525ad4fd5ae39be0c011edc5c45fdbff4337",
"user"=>{"work_phone"=>"",
"address"=>{"address1"=>"ad1",
"city"=>"any town",
"address2"=>"line2",
"zip"=>"12345",
"country"=>"USA",
"state"=>"CA"},
"profile_name"=>"pfname",
"home_phone"=>"",
"cell_phone"=>"",
"last_name"=>"last",
"first_name"=>"first",
"email"=>"",
"active"=>"1"}}
It is a simple 1-1 relationship - each user has one address. In this
use case I am trying to create data in two tables using a single
form.
I am certain that I am missing some more code that is required to
successfully save. Any clues greatly appreciated. Any suggestions to
implement in a different way are welcome. Can I explicitly write ruby
code to insert records into these tables even though I created the
objects using the rails scaffolding?
Thanks much
Vasu Kottilil
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2009-Dec-04 19:09 UTC
Re: ActiveRecord::AssociationTypeMismatch exception
On Dec 4, 6:58 pm, Vasu Kottilil <vasudeva...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > {"commit"=>"Create", > "authenticity_token"=>"1459525ad4fd5ae39be0c011edc5c45fdbff4337", > "user"=>{"work_phone"=>"", > "address"=>{"address1"=>"ad1", > "city"=>"any town", > "address2"=>"line2", > "zip"=>"12345", > "country"=>"USA", > "state"=>"CA"}, > "profile_name"=>"pfname", > "home_phone"=>"", > "cell_phone"=>"", > "last_name"=>"last", > "first_name"=>"first", > "email"=>"", > "active"=>"1"}} > > It is a simple 1-1 relationship - each user has one address. In this > use case I am trying to create data in two tables using a single > form.your code looks like you expect params[:address] to be set, but it isn''t (instead params[:user][:address] is set). Rails is then trying to do user.address = params[:user][:address] which doesn''t work because you''re trying to stuff a hash into an association. It can be made to work with the nested attributes stuff but that''s only in rails 2.3. You could change your views to not submit parameters in this way or read up on nested attributes. Fred> > I am certain that I am missing some more code that is required to > successfully save. Any clues greatly appreciated. Any suggestions to > implement in a different way are welcome. Can I explicitly write ruby > code to insert records into these tables even though I created the > objects using the rails scaffolding? > > Thanks much > > Vasu Kottilil-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Hi Fred,
Thank you so much for the quick response. It was quite helpful. I
really wanted to test this out with out upgrading to the newer
version. I made the changes to view/params
submittal and the controller code and now it seems to be working. I
can see two saved records after a create event.
new.html.erb:
<% form_for( @user,
:url => { :action => ''create'',
:first_name => @user.first_name,
:last_name => @user.last_name,
:home_phone => @user.home_phone,
:work_phone => @user.work_phone,
:cell_phone => @user.cell_phone,
:email => @user.email,
:profile_name => @user.profile_name,
:active => @user.active,
:address1 => @address.address1,
:address2 => @address.address2,
:city => @address.city,
:state => @address.state,
:country => @address.country
}
) do | f |
%>
----- rest of the form fields ---
In the users_controller.rb, removed the previous build invocation and
put these lines of code to manually set the FK for the association.
def create
Rails.logger.debug(params)
@user = User.new
@address = Address.new
@user.first_name = params[:user][:first_name]
@user.last_name = params[:user][:last_name]
@user.profile_name = params[:user][:profile_name]
@user.home_phone = params[:user][:home_phone]
@user.work_phone = params[:user][:work_phone]
@user.cell_phone = params[:user][:cell_phone]
@user.email = params[:user][:email]
@user.active = params[:user][:active]
@address.address1 = params[:user][:address][:address1]
@address.address2 = params[:user][:address][:address2]
@address.city = params[:user][:address][:city]
@address.state = params[:user][:address][:state]
@address.zip = params[:user][:address][:zip]
@address.country = params[:user][:address][:country]
respond_to do |format|
if @user.save
@address.user_id = @user.id
if @address.save
flash[:notice] = ''User was successfully created.''
Thanks again for the excellent comments,
best regards
Vasu
Vasu Kottilil
On Dec 4, 11:09 am, Frederick Cheung
<frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> On Dec 4, 6:58 pm, Vasu Kottilil
<vasudeva...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>
>
>
>
> > {"commit"=>"Create",
> >
"authenticity_token"=>"1459525ad4fd5ae39be0c011edc5c45fdbff4337",
> > "user"=>{"work_phone"=>"",
> > "address"=>{"address1"=>"ad1",
> > "city"=>"any town",
> > "address2"=>"line2",
> > "zip"=>"12345",
> > "country"=>"USA",
> > "state"=>"CA"},
> > "profile_name"=>"pfname",
> > "home_phone"=>"",
> > "cell_phone"=>"",
> > "last_name"=>"last",
> > "first_name"=>"first",
> > "email"=>"",
> > "active"=>"1"}}
>
> > It is a simple 1-1 relationship - each user has one address. In this
> > use case I am trying to create data in two tables using a single
> > form.
>
> your code looks like you expect params[:address] to be set, but it
> isn''t (instead params[:user][:address] is set).
> Rails is then trying to do user.address = params[:user][:address]
> which doesn''t work because you''re trying to stuff a hash
into an
> association. It can be made to work with the nested attributes stuff
> but that''s only in rails 2.3. You could change your views to not
> submit parameters in this way or read up on nested attributes.
>
> Fred
>
>
>
> > I am certain that I am missing some more code that is required to
> > successfully save. Any clues greatly appreciated. Any suggestions to
> > implement in a different way are welcome. Can I explicitly write ruby
> > code to insert records into these tables even though I created the
> > objects using the rails scaffolding?
>
> > Thanks much
>
> > Vasu Kottilil
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2009-Dec-05 11:06 UTC
Re: ActiveRecord::AssociationTypeMismatch exception
On Dec 4, 10:42 pm, Vasu Kottilil <vasudeva...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi Fred, > > Thank you so much for the quick response. It was quite helpful. I > really wanted to test this out with out upgrading to the newer > version. I made the changes to view/params > submittal and the controller code and now it seems to be working. I > can see two saved records after a create event. >I think you''re making things a little too complicated doing @user = User.new(params[:user]) ## --> line 45 @address = @user.address.build(params[:address]) is fine, as long as the two sets of parameters aren''t munged together. (eg use fields_for @address to create a separate form builder) Fred> new.html.erb: > > <% form_for( @user, > :url => { :action => ''create'', > :first_name => @user.first_name, > :last_name => @user.last_name, > :home_phone => @user.home_phone, > :work_phone => @user.work_phone, > :cell_phone => @user.cell_phone, > :email => @user.email, > :profile_name => @user.profile_name, > :active => @user.active, > :address1 => @address.address1, > :address2 => @address.address2, > :city => @address.city, > :state => @address.state, > :country => @address.country > } > ) do | f | > %> > > ----- rest of the form fields --- > > In the users_controller.rb, removed the previous build invocation and > put these lines of code to manually set the FK for the association. > > def create > > Rails.logger.debug(params) > @user = User.new > @address = Address.new > > @user.first_name = params[:user][:first_name] > @user.last_name = params[:user][:last_name] > @user.profile_name = params[:user][:profile_name] > @user.home_phone = params[:user][:home_phone] > @user.work_phone = params[:user][:work_phone] > @user.cell_phone = params[:user][:cell_phone] > @user.email = params[:user][:email] > @user.active = params[:user][:active] > > @address.address1 = params[:user][:address][:address1] > @address.address2 = params[:user][:address][:address2] > @address.city = params[:user][:address][:city] > @address.state = params[:user][:address][:state] > @address.zip = params[:user][:address][:zip] > @address.country = params[:user][:address][:country] > > respond_to do |format| > > if @user.save > @address.user_id = @user.id > if @address.save > flash[:notice] = ''User was successfully created.'' > > Thanks again for the excellent comments, > > best regards > Vasu > > Vasu Kottilil > > On Dec 4, 11:09 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > > > > On Dec 4, 6:58 pm, Vasu Kottilil <vasudeva...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > {"commit"=>"Create", > > > "authenticity_token"=>"1459525ad4fd5ae39be0c011edc5c45fdbff4337", > > > "user"=>{"work_phone"=>"", > > > "address"=>{"address1"=>"ad1", > > > "city"=>"any town", > > > "address2"=>"line2", > > > "zip"=>"12345", > > > "country"=>"USA", > > > "state"=>"CA"}, > > > "profile_name"=>"pfname", > > > "home_phone"=>"", > > > "cell_phone"=>"", > > > "last_name"=>"last", > > > "first_name"=>"first", > > > "email"=>"", > > > "active"=>"1"}} > > > > It is a simple 1-1 relationship - each user has one address. In this > > > use case I am trying to create data in two tables using a single > > > form. > > > your code looks like you expect params[:address] to be set, but it > > isn''t (instead params[:user][:address] is set). > > Rails is then trying to do user.address = params[:user][:address] > > which doesn''t work because you''re trying to stuff a hash into an > > association. It can be made to work with the nested attributes stuff > > but that''s only in rails 2.3. You could change your views to not > > submit parameters in this way or read up on nested attributes. > > > Fred > > > > I am certain that I am missing some more code that is required to > > > successfully save. Any clues greatly appreciated. Any suggestions to > > > implement in a different way are welcome. Can I explicitly write ruby > > > code to insert records into these tables even though I created the > > > objects using the rails scaffolding? > > > > Thanks much > > > > Vasu Kottilil-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.