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?