Been trying to sort this for over a day now, and I am sure that it is something simple that I am missing.
I have a project, which can have one main category and two optional categories. My relevant code for the project model:
has_many :project_categories
has_one :optional_category_1,
:through => :project_categories,
:conditions => 'is_main_category = 0',
:order => 'category_id',
:source => :category,
:class_name => 'Category'
has_one :optional_category_2,
:through => :project_categories,
:conditions => 'is_main_category = 0',
:order => 'category_id DESC',
:source => :category,
:class_name => 'Category'
has_one :main_category,
:through => :project_categories,
:conditions => 'is_main_category = 1',
:source => :category,
:class_name => 'Category'
The relevant code from the Category class:
has_many :project_categories
has_many :projects, :through => :project_categories, :source => :project
and from the ProjectCategory class:
class ProjectCategory < ActiveRecord::Base
belongs_to :project
belongs_to :category
end
In my view:
Main Category: <%= f.select(:main_category, Category.find(:all, :order => 'parent_id, categories.desc').collect {|c| [c.display_name, c.id] }, :prompt => "Select a Main Category") %><br>
Optional Category 1: <%= f.select(:optional_category_1, Category.find(:all, :order => 'parent_id, categories.desc').collect {|c| [c.display_name, c.id] }, :prompt => "Select an Optional Category") %><br>
Optional Category 2: <%= f.select(:optional_category_2, Category.find(:all, :order => 'parent_id, categories.desc').collect {|c| [c.display_name, c.id] }, :prompt => "Select an Optional Category") %><br>
and in my controller:
@project.attributes = params[:project]
Ok, so when updating an existing project, I get the following error:
undefined method `update_attributes' for #<Class:0x82efce0>
and the relevant stack trace:
C:/Software/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/associations.rb:1255:in `main_category='
C:/Software/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2745:in `send'
C:/Software/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2745:in `attributes='
C:/Software/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2741:in `each'
C:/Software/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2741:in `attributes='
C:/Development/craftbits_rails/app/controllers/projects_controller.rb:85:in `manage_project'
Is it saying that there is an issue with main_category and that it is a generic class? But why? The association defines it correctly AFAIK.
Any help appreciated!
Vikram
I know this doesn’t address the error you’re getting, but I’d suggest using three one-to-many relationships instead of one many-to-many relationship.
The conventional purpose of
has_many :through => ...(many-to-many) is for when you have something likestudentsandclasses. A student can be in any number of classes. A class can have any number of students. Totally arbitrary numbers on both sides of the relationship.But that isn’t your situation here. Your projects can be in exactly one main category, one optional category 1, and one optional category 2. It’s a totally different problem and it isn’t the problem that
has_many :throughis designed to solve.I suggest this arrangement:
Then you’ll be able to do stuff like: