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.