# Belongs\_to behaviour and missing method updated?

**URL:** <https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048>\
**Category:** Rails\
**Created:** [December 20, 2006, 11:37pm UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048 "2006-12-20T23:37:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 20, 2006, 11:37pm UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/1 "2006-12-20T23:37:23Z")

</div>

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](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+`updated%3F'&rnum=1#11bbc512dd6215bf](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

```

---

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 21, 2006, 11:56am UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/2 "2006-12-21T11:56:25Z")

</div>

Michael H. 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 F.

---

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 22, 2006, 2:04am UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/3 "2006-12-22T02:04:13Z")

</div>

Agnieszka F. wrote:

> Michael H. 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:

Nationality   
 \<%= options\_from\_collection\_for\_select(@countries, :id, :name, @selected) %\>

…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
```

---

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 22, 2006, 10:18pm UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/4 "2006-12-22T22:18:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 22, 2006, 5:13am UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/5 "2006-12-22T05:13:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 24, 2006, 2:02am UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/6 "2006-12-24T02:02:05Z")

</div>

Adam R. 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

---

<div class="post-metadata">

**Author:** ![teddio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b3f665/32.png) [@teddio](https://www.ruby-forum.com/u/teddio)\
**Post date:** [December 29, 2006, 12:05pm UTC](https://www.ruby-forum.com/t/belongs-to-behaviour-and-missing-method-updated/80048/7 "2006-12-29T12:05:33Z")

</div>

I was referring to the parameter passed in from the view…

so then your html would look like this:

\<%= options\_from\_collection\_for\_select(@countries, :id, :name,  
@selected) %\>

I believe that should work and not require querying the Nationality  
database.

Adam
