Question

essayé de régler ce problème depuis plus d'un jour, et je suis sûr qu'il est quelque chose de simple que je suis absent.

J'ai un projet, ce qui peut avoir une catégorie principale et deux catégories en option. Mon code correspondant pour le modèle de projet:

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'

Le code correspondant de la catégorie classe:

has_many :project_categories
has_many :projects, :through => :project_categories, :source => :project

et de la classe ProjectCategory:

class ProjectCategory < ActiveRecord::Base
  belongs_to :project
  belongs_to :category
end

À mon avis:

    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>

et dans mon contrôleur:

      @project.attributes = params[:project]

Ok, donc quand la mise à jour d'un projet existant, je reçois l'erreur suivante:

undefined method `update_attributes' for #<Class:0x82efce0>

et la trace de la pile concernée:

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'

Est-il dire qu'il ya un problème avec main_category et qu'il est une classe générique? Mais pourquoi? L'association définit correctement AFAIK.

Toute aide appréciée!

Vikram

Était-ce utile?

La solution

Je sais que cela ne résout pas l'erreur que vous obtenez, mais je suggère d'utiliser un trois à de nombreuses relations au lieu d'un grand nombre à plusieurs.

Le but classique de has_many :through => ... (many-to-many) est pour quand vous avez quelque chose comme students et classes. Un étudiant peut être tout nombre de classes. Une classe peut avoir un certain nombre d'étudiants . nombres totalement arbitraire des deux côtés de la relation.

Mais ce n'est pas votre situation ici. Vos projets peuvent être exactement une catégorie principale, une catégorie en option 1, et une catégorie en option 2. Il est un problème tout à fait différent et il est pas le problème que has_many :through est conçu pour résoudre.

Je suggère cet arrangement:

class Project < ActiveRecord::Base

  belongs_to :main_category, :class_name => "Category",
    :foreign_key => 'main_category_id'

  belongs_to :optional_category_1, :class_name => "Category",
    :foreign_key => 'optional_category_1_id'

  belongs_to :optional_category_2, :class_name => "Category",
    :foreign_key => 'optional_category_2_id'

end

class Category < ActiveRecord::Base

  has_many :main_category_projects, :class_name => "Project",
    :foreign_key => 'main_category_id'

  has_many :optional_category_1_projects, :class_name => "Project",
    :foreign_key => 'optional_category_1_id'

  has_many :optional_category_2_projects, :class_name => "Project",
    :foreign_key => 'optional_category_2_id'

end

Ensuite, vous serez en mesure de faire des choses comme:

my_project.main_category

my_category.optional_category_1_projects

# etc...

Autres conseils

Peut-être changer le contrôleur à quelque chose comme:

@project = Project.find(params[:id])
@project.update_attributes(params[:project])

Vous devrez peut-être utiliser main_category_id dans votre vue, i.e..

Main Category: <%= f.select(:main_category_id, ...) %>

Vous appelez update_attributes, mais main_category est pas correctement un attribut - c'est une association. main_category_id est un attribut.

Où êtes-vous @project de? Est-ce que vous faites juste un Project.find(params[:project_id]) normal ou quelque chose?

J'ai essayé de jeter dans une déclaration de debugger et de voir quelle classe l'@project est et quelles méthodes il a sur elle?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top