collection_select fails to work for "edit" but works great for "new"

Hi, all,

  I setup a drop down box that has data populated by the database.

This is for a simple application where by I am trying to add a new
"Part".
A part has a category and sub category.
The latter is optional.

When a category has been selected, an ajax query is made to the
database backend to
extract the subcategory options available for the selected category.

This has been implemented and works great for the task of adding a new
"Part" entry (ie. http://localhost:3000/parts/new) .

I did it by refering to the explanation in http://shiningthrough.co.uk/blog/show/6.
It was good.

Nevertheless, when I need to edit a given part (ie. http://localhost:3000/parts/22/edit),
I keep getting this silly error message below.
"undefined method `map' for "#<Category:0x103231d20>":Category".

This is the full extract of the error messages:

============Extract Begin===============================
NoMethodError in Parts#edit

Showing app/views/categories/_form.html.erb where line #3 raised:

undefined method `map' for "#<Category:0x1036113c8>":Category

Extracted source (around line #3):

1: <%= label :category, :id, 'Category' %> <br />
2: <%= collection_select(
3: :part,
4: 'category_id',
5: @categories,
6: :id,

Trace of template inclusion: app/views/parts/edit.html.erb
============Extract End===============================

Here's what my other files look like:

app/views/parts/new.html.erb

and by the way, the parts controller looks the following:

  def new
    @part = Part.new
    @categories = Category.all

    respond_to do |format|
      format.html # new.html.erb
      format.xml { render :xml => @part }
    end
  end

  # GET /parts/1/edit
  def edit
    @part = Part.find(params[:id])
    @categories = @part.category

    respond_to do |format|
      format.html # edit.html.erb
      format.xml { render :xml => @part }
    end
  end

You don't show your Part model, but I suspect that it looks something like:

class Part < ActiveRecord::Base
  belongs_to :category
end

This allows you to do something like:

@part = Part.find(params[:id])
@category = @part.category

Note the subtle difference between what I wrote and what you wrote in
your edit view: (@category vs @categories)

A part belongs to a single category. When you reference
@part.category, you get that single category -- the category to which
the part belongs. In particular, you don't get a list of categories.
Since you don't have a list of categories, you don't have a
"collection" to which you can pass to #collection_select.

If you want to be able to use the Edit view to change the category to
which a part belongs, then you should probably do the same thing you
did in the action for your New view and do:

  @categories = Category.all

--wpd

and by the way, the parts controller looks the following:

def new
@part = Part.new
@categories = Category.all

respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @part }
end
end

# GET /parts/1/edit
def edit
@part = Part.find(params[:id])
@categories = @part.category

That makes @categories only be a single category, which I think may be
the cause of the problem.

Colin

aha! fixed it.

1) Removed usage of @categories in the collection_select call in the
parts/new and edit views. Replaced it with 'Category.all'
2) Removed population of @categories by means of Categories.all in
the parts controller.
3) Removed putting in of 'local' hashref of :categories => @categories
in the category/form partial (
app/views/categories/_form.html.erb ).

ah, yes, as in doing so in new & edit methods in the Parts controller?