# Collection\_select question

**URL:** <https://www.ruby-forum.com/t/collection-select-question/139810>\
**Category:** Rails\
**Created:** [June 7, 2008, 11:15am UTC](https://www.ruby-forum.com/t/collection-select-question/139810 "2008-06-07T11:15:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nuky](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e99b99/32.png) [@nuky](https://www.ruby-forum.com/u/nuky)\
**Post date:** [June 7, 2008, 11:15am UTC](https://www.ruby-forum.com/t/collection-select-question/139810/1 "2008-06-07T11:15:05Z")

</div>

Hello,

I’m pretty new to Ruby on Rails (ROR) so I’m sorry if this is a silly  
thing to ask. I have tried looking at several tutorials online but  
most of them are for the earlier version of ROR and even the API is  
not helping me too much!

Basically I would like to create a drop down list in a form. I have  
simplified my problem so that you’ll be able to understand it in a few  
lines.

A simple diagram is here:  
[http://learningspirit.co.uk/class\_diagram.png](http://learningspirit.co.uk/class_diagram.png)

The migration and model files are here:

## db/migrate/003\_books.rb

class Books \< ActiveRecord::Migration  
def self.up  
create\_table :books do |t|  
t.column :title, :string, :limit =\> 32, :null =\> false  
t.column :price, :float  
t.column :subject\_id, :integer  
t.column :description, :text  
t.column :created\_at, :timestamp  
end  
end

def self.down  
drop\_table :books  
end  
end

## db/migrate/004\_subjects.rb

class Subjects \< ActiveRecord::Migration  
def self.up  
create\_table :subjects do |t|  
t.column :name, :string  
end

```
Subject.create :name => "Physics"
Subject.create :name => "Mathematics"
Subject.create :name => "Chemistry"
Subject.create :name => "Psychology"
Subject.create :name => "Geography"

```

end

def self.down  
drop\_table :subjects  
end  
end

## app/model/book.rb

class Book \< ActiveRecord::Base  
belongs\_to :subject  
validates\_presence\_of :title  
validates\_numericality\_of :price, :message=\>“Error message”  
end

## app/model/subject.rb

class Subject \< ActiveRecord::Base  
has\_many :books  
end

The relevant book\_controller.rb methods are:  
def new  
@book = Book.new  
@subjects = Subject.find(:all)  
end

def create  
@book = Book.new(params[:book])  
if @book.save  
redirect\_to :action =\> ‘list’  
else  
@subjects = Subject.find(:all)  
render :action =\> ‘new’  
end  
end

The problem I have is in the view for the form to create a new book  
entry. The view (app/views/book/new.html.erb) is looking like this at  
the moment:

# Add new book
\<% form\_for :book, @book, :url =\> { :action =\> "create" } do |f| %\>

Title: \<%= text\_field @book, :title %\>

Price: \<%= text\_field @book, :price %\>

Subject: \<%= collection\_select :book, :subject\_id, @subjects, :id, :name %\>

Description: \<%= text\_area @book, :description %\>

\<%= f.submit "Create"%\>

\<% end %\> \<%= link\_to 'Back', {:action =\> 'list'} %\>

My problem is that I cannot get the drop down list to work! I have  
tried select (instead of collection\_sort) but I am always getting  
errors. At the moment I have the following error:

undefined method `subject\_id’ for #\<Book id: nil, created\_at: nil,  
updated\_at: nil\>

I don’t understand this at all because from the documentation, there  
should be a method there!

Please could some help me? What exactly are the arguments for the  
collection\_select method? What is wrong with my collection\_select  
call?

Thank you very much and I hope this wasn’t too long winded!  
Inuka.

---

<div class="post-metadata">

**Author:** ![nuky](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e99b99/32.png) [@nuky](https://www.ruby-forum.com/u/nuky)\
**Post date:** [June 7, 2008, 11:27am UTC](https://www.ruby-forum.com/t/collection-select-question/139810/2 "2008-06-07T11:27:26Z")

</div>

On Jun 7, 1:33 am, nuky [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

Did you change a migration after having run it (for example to add  
subject\_id to the books table). Rails won’t notice if you do that. You  
either need to create a new migration when you want a changed like  
that or you need to migrate down and then up again.

Fred

---

<div class="post-metadata">

**Author:** ![nuky](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e99b99/32.png) [@nuky](https://www.ruby-forum.com/u/nuky)\
**Post date:** [June 7, 2008, 12:31pm UTC](https://www.ruby-forum.com/t/collection-select-question/139810/3 "2008-06-07T12:31:06Z")

</div>

Hi,  
So you’re on here too huh?

I think the problem is you’re trying to access the subject model from  
within the book model…so rails is not gonna understand what  
subject\_id is and is therefore probably looking for a method by that  
name which doesn’t exist.

I haven’t tried this out myself yet but I think this might help you:

> **[\#73 Complex Forms Part 1 - RailsCasts](http://railscasts.com/episodes/73-complex-forms-part-1)**
>
> Short Ruby on Rails screencasts containing tips, tricks and tutorials. Great for both novice and experienced web developers.

---

<div class="post-metadata">

**Author:** ![nuky](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e99b99/32.png) [@nuky](https://www.ruby-forum.com/u/nuky)\
**Post date:** [June 8, 2008, 12:38pm UTC](https://www.ruby-forum.com/t/collection-select-question/139810/4 "2008-06-08T12:38:33Z")

</div>

Thank you for the replies!

It turns out that there were many problems with my form. I fixed them  
and it is pasted below in case it will be of some use to someone else  
having problems with collection\_sort!

% if flash[:notice] %\>  
\<%= flash[:notice] %\>  
\<% end %\>

# Add new book
\<% form\_for :book, @book, :url =\> { :action =\> "create" } do |f| %\>

Title: \<%= f.text\_field :title %\>

Price: \<%= f.text\_field :price %\>

Subject: \<%= f.collection\_select :subject\_id, @subjects, :id, :name %\>

Description: \<%= f.text\_area :description %\>

\<%= f.submit "Create"%\>

\<% end %\>

\<%= link\_to ‘Back’, {:action =\> ‘list’} %\>

Thank you.
