# Am I going too far or Rails is just confusing? was {validate

**URL:** <https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580>\
**Category:** Rails\
**Created:** [January 3, 2006, 9:28pm UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580 "2006-01-03T21:28:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 3, 2006, 9:28pm UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/1 "2006-01-03T21:28:06Z")

</div>

Thanks for the input Blair Z. and Chris (Nolan and Hall), and for  
others.

If all of you have time, please follow this (the question still  
relates to the previous posts by me):

I have provided full steps to reproduce the symptoms.  
If it matters, I’m running Ruby 1.8.2, Rails 1.0, and MySQL 5.0.15 on  
Windows XP Professional.

1. First, the setup

## MySQL

create database testdb;

create table ranks (id tinyint unsigned not null auto\_increment,  
description varchar(50) not null unique, primary key(id));

create table customers (id mediumint unsigned not null auto\_increment,  
name varchar(50) not null,  
phone varchar(25), address varchar(50), rank\_id tinyint unsigned not  
null, primary key(id),  
foreign key (rank\_id) references ranks(id));

Leave the tables blank. This is intentional.

## Rails

> rails myapp  
> cd myapp  
> ruby script\server  
> ruby script\generate scaffold rank ‘admin/ranks’  
> ruby script\generate scaffold customer ‘admin/customers’

## Edit the models

app/models/rank.rb:  
class Rank \< ActiveRecord::Base  
has\_many :customers  
validates\_presence\_of :description  
validates\_length\_of :description, :maximum =\> 50  
validates\_uniqueness\_of :description  
end

app/models/customer.rb:  
class Customer \< ActiveRecord::Base  
belongs\_to :rank  
validates\_presence\_of :name  
validates\_length\_of :name, :maximum =\> 50  
validates\_presence\_of :rank  
validates\_associated :rank  
end

## Edit app/views/admin/customers/\_form.html

\<%= error\_messages\_for ‘customer’ %\>

Name  
\<%= text\_field 'customer', 'name' %\>

Phone  
\<%= text\_field 'customer', 'phone' %\>

Address  
\<%= text\_field 'customer', 'address' %\>

Rank  
\<%= select 'customer', 'rank', Rank.find\_all.collect { |r| [r.description, r.id] } %\>

1. Let’s try

Go to [http://localhost:3000/admin/customers/new](http://localhost:3000/admin/customers/new)  
Then just press the “Create” button  
Rails responds:

2 errors prohibited this customer from being saved

There were problems with the following fields:

```
* Name can't be blank
* Rank can't be blank

```

The name textbox and the rank select field are highlighted with red.

SMART!!!

1. Try this then  
Still at [http://localhost:3000/admin/customers/new](http://localhost:3000/admin/customers/new)  
Fill the name with whatever you want, then press the “Create” button  
Rails responds:

1 error prohibited this customer from being saved

There were problems with the following fields:

```
* Rank can't be blank

```

The rank select field is the only one highlighted with red.

I LOVE RAILS!!!

1. O O, what gives?  
Head to [http://localhost:3000/admin/ranks/new](http://localhost:3000/admin/ranks/new)  
Type in whatever description u want, and press the “Create” button  
If all is OK, you will have 1 rank already in the ranks table.

Go back to [http://localhost:3000/admin/customers/new](http://localhost:3000/admin/customers/new)  
Now the rank select field will contain 1 option

Without typing anything, just press the “Create” button.  
Oh my God, I don’t understand this:  
Rails responds:  
ActiveRecord::AssociationTypeMismatch in Admin/customers#create

Rank expected, got String

1. What I have tried  
Don’t give up first John, try changing file  
app/views/admin/customers/\_form.html line #13-14 with:

Rank  
\<%= select 'customer', 'rank\_id', Rank.find\_all.collect { |r| [r.description, r.id] } %\>

Then change app/models/customer.rb line #5-6 with these:

validates\_presence\_of :rank\_id  
validates\_associated :rank\_id

Rush to [http://localhost:3000/admin/customers/new](http://localhost:3000/admin/customers/new)  
Don’t type anything, just press “Create”.  
Rails bombs:

NoMethodError in Admin/customers#create

undefined method `valid?’ for 4:Fixnum

No good.  
I go to MySQL and issue delete from ranks;  
Back to initial setup, no records at all.

Go to [http://localhost:3000/admin/customers](http://localhost:3000/admin/customers) and click on “New customer”  
Rails produces same error as before “undefined method `valid?’ for  
0:Fixnum”

What happened? What’s the best way to get rid of “Rank expected, got  
String” kind of error.  
I understand that Ruby is searching for object of class Rank but it  
faces a String.  
How to overcome the problem?

Sorry for the long and so newbie e-mail. Pardon my English too. Tq so  
very much,  
John

---

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 3, 2006, 9:39pm UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/2 "2006-01-03T21:39:41Z")

</div>

> create table customers (id mediumint unsigned not null auto\_increment,  
> name varchar(50) not null,  
> phone varchar(25), address varchar(50), rank\_id tinyint unsigned not  
> null, primary key(id),  
> foreign key (rank\_id) references ranks(id));

> ## Edit app/views/admin/customers/\_form.html
> 
> Rank  
> \<%= select 'customer', 'rank', Rank.find\_all.collect { |r| [r.description, r.id] } %\>

I think your problem is that the form is setting the ‘rank’ attribute  
but your table is expecting a ‘rank\_id’ attribute. Try changing the  
‘rank’ in the select to 'rank\_id’and have your model validate against  
:rank\_id instead of :rank.

---

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 3, 2006, 9:53pm UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/3 "2006-01-03T21:53:48Z")

</div>

Hello John !

2006/1/3, John I. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Rank  
> \<%= select 'customer', 'rank', Rank.find\_all.collect { |r| [r.description, r.id] } %\>

You should investigate using collection\_select. In fact, I just  
updated my blog today with a new article about this:  
[http://blog.teksol.info/articles/2006/01/03/belongs\_to-user-interface-take-ii](http://blog.teksol.info/articles/2006/01/03/belongs_to-user-interface-take-ii)

The gist of the article was this:

Rank  
\<%= collection\_select 'customer', 'rank', Rank.find(:all), :id, :name %\>

Hope that helps !

---

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 4, 2006, 7:20am UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/4 "2006-01-04T07:20:05Z")

</div>

On 1/4/06, Francois B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> [http://blog.teksol.info/articles/2006/01/03/belongs\_to-user-interface-take-ii](http://blog.teksol.info/articles/2006/01/03/belongs_to-user-interface-take-ii)

I have read your article. Nice one really. Thanks a lot.

However, it doesn’t work for me. Following your article, I change my  
app/views/admin/customers/\_form.rhtml to:

and when I head to [http://localhost:3000/admin/customers/new](http://localhost:3000/admin/customers/new), Rails  
bombs with this message:

NoMethodError in Admin/customers#new

Showing app/views/admin/customers/\_form.rhtml where line #14 raised:

undefined method `error\_messages\_on’ for #\<#Class:0x39acc60:0x39acb88\>

Doh!

How come an error\_messages\_on is not defined?

John

---

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 4, 2006, 1:40am UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/5 "2006-01-04T01:40:59Z")

</div>

> Then change app/models/customer.rb line #5-6 with these:
> 
> validates\_presence\_of :rank\_id  
> validates\_associated :rank\_id

That should be:  
validates\_presence\_of :rank\_id  
validates\_associated :rank

Also, I don’t use MySQL, but doesn’t Rails treat “tinyint” values as  
booleans, when using that adapter?  
I would go back and make all of my “id” columns real deal integers,  
rather than tinyint, mediumint, etc.

---

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 4, 2006, 12:57pm UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/6 "2006-01-04T12:57:40Z")

</div>

On 4.1.2006, at 8.16, John I. wrote:

> Doh!
> 
> How come an error\_messages\_on is not defined?

There is no such function. There’s error\_message\_on and  
error\_messages\_for. You’re looking for the former. You can check  
things like this easily from the Rails api [1].

//jarkko

[1] [Peak Obsession](http://api.rubyonrails.com/classes/ActionView/Helpers/)  
ActiveRecordHelper.html#M000371

---

<div class="post-metadata">

**Author:** ![John\_I](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/74df32/32.png) [@John\_I](https://www.ruby-forum.com/u/John_I)\
**Post date:** [January 4, 2006, 7:41am UTC](https://www.ruby-forum.com/t/am-i-going-too-far-or-rails-is-just-confusing-was-validate/51580/7 "2006-01-04T07:41:22Z")

</div>

Kevin O. wrote:

> I think your problem is that the form is setting the ‘rank’ attribute  
> but your table is expecting a ‘rank\_id’ attribute. Try changing the  
> ‘rank’ in the select to 'rank\_id’and have your model validate against  
> :rank\_id instead of :rank.

If you read my post carefully, you can tell that I’ve already tried  
that.

Still, it doesn’t work.

Tq,  
John
