collection_select question

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

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:

<h1>Add new book</h1> <% form_for :book, @book, :url => { :action => "create" } do |f| %> <p> <label>Title</label>: <%= text_field @book, :title %> </p> <p> <label>Price</label>: <%= text_field @book, :price %> </p> <p> <label>Subject</label>: <%= collection_select :book, :subject_id, @subjects, :id, :name %> </p> <p> <label>Description</label>: <%= text_area @book, :description %> </p> <p> <%= f.submit "Create"%> </p> <% 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.

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

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:

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 %>

<h1>Add new book</h1> <% form_for :book, @book, :url => { :action => "create" } do |f| %> <p> Title: <%= f.text_field :title %> </p>

<p> Price: <%= f.text_field :price %> </p>

<p> Subject: <%= f.collection_select :subject_id, @subjects, :id, :name %> </p>

<p> Description: <%= f.text_area :description %> </p>

<p> <%= f.submit "Create"%> </p>

<% end %>

<%= link_to 'Back', {:action => 'list'} %>

Thank you.