Hi, I''ve got a really simple model and controller which are producing an error. The model is one line: class NaturalPerson < ActiveRecord::Base belongs_to :nationality, {:class_name => "Country"} end and the controller, specifically the create action, is equally simple: class NaturalPeopleController < ApplicationController def create person = NaturalPerson.new(params[:natural_person]) if person.save flash[:notice] = "Person was successfully created" redirect_to :action => "list" else render_scaffold(''new'') end end end If I run the code like this I get this error: ActiveRecord::AssociationTypeMismatch in Natural peopleController#create Country expected, got String I have given ActiveRecord enough information to know it should instantiate a Country and assign to "nationality", no? OK, so I need to do it myself in a constructor for the NaturalPerson model: def initialize(params) @postal_address = params[:postal_address] @fax_number = params[:fax_number] @name = params[:name] @phone_number = params[:phone_number] @dob = Date.civil(params["dob(1i)"].to_i, params["dob(2i)"].to_i, params["dob(3i)"].to_i) @visa =params[:visa] @mobile_number = params[:mobile_number] @email_address = params[:email_address] @nationality = Country.find(params[:nationality].to_i) end Now I get this error: NoMethodError in Natural peopleController#create undefined method `updated?'' for #<Country:0x412cb0a0 @attributes={"name"=>"TONGA", "id"=>"220"}> A search of the web and usenet suggests that the "definitive" reason for this error is described in this post: http://lists.rubyonrails.org/pipermail/rails/2006-March/026246.html "my problem was caused by a badly chosen name of a variable in the validates method of my interface model. Originally I called it @device, after renaming it the error was gone." Unfortuately the post doesn''t say what it was about the variable name what was bad. This thread provides another useful tidbit of information: http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/28afcde31492865f/11bbc512dd6215bf?lnk=st&q=undefined+method+%60updated%3F%27&rnum=1#11bbc512dd6215bf "Looking back at the reason, it would never get into the block that I mentioned in my original post if the :belongs_to object is null and if i have a different variable name, that would be the case and the association is only saved due to the link from the Doctor''s side." OK. In my case the belongs_to object *is* nil because it hasn''t been assigned a value yet. The name of my foreign key was originally "nationality" but, without really knowing what was causing the problem, I thought there might be some conflict with the instance variable so I changed the field to "country_id". Hence this code in the model: belongs_to :nationality, {:class_name => "Country"} which implies a foreign key of "country_id". So I''m at a point where I don''t think the previous examples of this error apply to me. If anyone has any suggestions I would be extremely grateful! Regards, Michael -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Agnieszka Figiel
2006-Dec-21 10:56 UTC
Re: belongs_to behaviour and missing method updated?
Michael Henry wrote:> Hi, > > I''ve got a really simple model and controller which are producing an > error. The model is one line:Hello, it would be helpful to know what params[:natural_person] looks like to analyze the first of the errors you described (one without overriding the constructor) -- Agnieszka Figiel -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Agnieszka Figiel wrote:> Michael Henry wrote: >> Hi, >> >> I''ve got a really simple model and controller which are producing an >> error. The model is one line: > > Hello, > > it would be helpful to know what params[:natural_person] looks like to > analyze the first of the errors you described (one without overriding > the constructor)Sure, here it is with some formatting to make it more readable: Parameters: { "natural_person"=> { "postal_address"=>"", "fax_number"=>"", "name"=>"Maikolo", "phone_number"=>"", "dob(1i)"=>"2006", "visa"=>"", "dob(2i)"=>"12", "dob(3i)"=>"14", "mobile_number"=>"", "email_address"=>"", "nationality"=>"220" }, "commit"=>"Create" } The view that produced the drop-down for "Nationality" looks like this: <p> <label for="natural_person_nationality">Nationality</label> <br /> <select id="natural_person_nationality" name="natural_person[nationality]" /> <%= options_from_collection_for_select(@countries, :id, :name, @selected) %> </select> </p> ...where @countries and @selected are defined in the controller as: @countries = Country.find(:all) @selected = Country.find_by_name("TONGA").id @selected has the value of 220 (I didn''t change the country before submitting the form). Regards, Michael -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I''ve found a workaround as outlined below.> I''ve got a really simple model and controller which are producing an > error. The model is one line: > > class NaturalPerson < ActiveRecord::Base > belongs_to :nationality, {:class_name => "Country"} > endI''ve made no changes to the model. The constructor I included in my initial post has been discarded.> and the controller, specifically the create action, is equally simple: > > class NaturalPeopleController < ApplicationController > def create > person = NaturalPerson.new(params[:natural_person]) > > if person.save > flash[:notice] = "Person was successfully created" > redirect_to :action => "list" > else > render_scaffold(''new'') > end > end > endI''ve inserted this line of code before I instantiate the NaturalPerson: params[:natural_person][:nationality] = Country.find(params[:country].to_i) Note that I''m referring to a new form element: "country". I have changed the view so that this is the name of the country drop-down. I don''t suppose anybody''s reading this but it gives me a sense of closure to put my workaround on the list :) Michael -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Just thinking out loud here.. What about if you changed the parameter to nationality_id instead of nationality. That way, when the constructor is creating the object calls the method nationality_id= which is expecting a integer instead of the the method its currently calling nationality= which is created from the belongs_to declaration. In either case, your workaround does the trick but this might be a little more efficient. Adam On 12/21/06, Michael Henry <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > I''ve found a workaround as outlined below. > > > I''ve got a really simple model and controller which are producing an > > error. The model is one line: > > > > class NaturalPerson < ActiveRecord::Base > > belongs_to :nationality, {:class_name => "Country"} > > end > > I''ve made no changes to the model. The constructor I included in my > initial post has been discarded. > > > and the controller, specifically the create action, is equally simple: > > > > class NaturalPeopleController < ApplicationController > > def create > > person = NaturalPerson.new(params[:natural_person]) > > > > if person.save > > flash[:notice] = "Person was successfully created" > > redirect_to :action => "list" > > else > > render_scaffold(''new'') > > end > > end > > end > > I''ve inserted this line of code before I instantiate the NaturalPerson: > > params[:natural_person][:nationality] > Country.find(params[:country].to_i) > > Note that I''m referring to a new form element: "country". I have changed > the view so that this is the name of the country drop-down. > > I don''t suppose anybody''s reading this but it gives me a sense of > closure to put my workaround on the list :) > > Michael > > > > -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Adam Rails wrote:> What about if you changed the parameter to nationality_id instead of > nationality.Do you mean the association? It originally referred to a foreign key which was also called "nationality" but I changed the foreign key to "country_id" so that: a) it conforms to the ActiveRecord convention, and b) removes any possibility of conflict between the association and field names. Unfortunately this change didn''t affect the error.> That way, when the constructor is creating the object calls > the method nationality_id= which is expecting a integer instead of the > the > method its currently calling nationality= which is created from the > belongs_to declaration.The belongs_to invocation *should* cause the same code to be run regardless of the name of the association. I''m happy to be corrected on that point. Also, I think the "_id" naming convention only applies to the database and as such should be kept in the persistence layer and not make its way to the middle tier of my application.> In either case, your workaround does the trick but this might be a > little more efficient.I''m in the early stages of developing this application so I''m not that bothered by efficiency yet. My main problem with the workaround is that the Country.find() method will have to be invoked every time I want to create a NaturalPerson. ie, it violates the DRY principle. Michael -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I was referring to the parameter passed in from the view... so then your html would look like this: <select id="natural_person_nationality_id" name="natural_person[nationality_id]" /> <%= options_from_collection_for_select(@countries, :id, :name, @selected) %> I believe that should work and not require querying the Nationality database. Adam On 12/23/06, Michael Henry <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > Adam Rails wrote: > > What about if you changed the parameter to nationality_id instead of > > nationality. > > Do you mean the association? It originally referred to a foreign key > which was also called "nationality" but I changed the foreign key to > "country_id" so that: a) it conforms to the ActiveRecord convention, and > b) removes any possibility of conflict between the association and field > names. Unfortunately this change didn''t affect the error. > > > That way, when the constructor is creating the object calls > > the method nationality_id= which is expecting a integer instead of the > > the > > method its currently calling nationality= which is created from the > > belongs_to declaration. > > The belongs_to invocation *should* cause the same code to be run > regardless of the name of the association. I''m happy to be corrected on > that point. Also, I think the "_id" naming convention only applies to > the database and as such should be kept in the persistence layer and not > make its way to the middle tier of my application. > > > In either case, your workaround does the trick but this might be a > > little more efficient. > > I''m in the early stages of developing this application so I''m not that > bothered by efficiency yet. My main problem with the workaround is that > the Country.find() method will have to be invoked every time I want to > create a NaturalPerson. ie, it violates the DRY principle. > > Michael > > > > -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---