Frage

versucht, diese zu sortieren jetzt einen Tag über, und ich bin sicher, dass es etwas einfacher ist, dass ich fehle.

Ich habe ein Projekt, das eine Hauptkategorie und zwei optionale Kategorien hat. Mein entsprechender Code für das Projektmodell:

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'

Der entsprechende Code aus der Kategorie Klasse:

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

und von der ProjectCategory Klasse:

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

Aus meiner Sicht:

    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>

und in meinem Controller:

      @project.attributes = params[:project]

Ok, also wenn ein vorhandenes Projekt zu aktualisieren, erhalte ich folgende Fehlermeldung:

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

und der entsprechende 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'

Ist zu sagen, dass es ein Problem mit main_category ist und dass es eine generische Klasse? Aber wieso? Der Verband definiert es richtig AFAIK.

Jede Hilfe willkommen!

Vikram

War es hilfreich?

Lösung

Ich weiß, das den Fehler nicht adressieren Sie bekommen, aber ich würde empfehlen die Verwendung von drei Eins-zu-viele-Beziehungen statt einer many-to-many-Beziehung.

Der herkömmliche Zweck has_many :through => ... (many-to-many) gilt, wenn Sie so etwas wie students und classes haben. Ein Student kann in jeder Anzahl der Klassen sein. Eine Klasse kann haben alle Anzahl der Studenten. Völlig beliebige Zahlen auf beiden Seiten der Beziehung.

Aber das ist hier nicht Ihre Situation. Ihre Projekte können in genau einer Hauptkategorie sein, eine optionale Kategorie 1 und eine optionale Kategorie 2. Es ist ein ganz anderes Problem, und es ist nicht das Problem, dass has_many :through ausgelegt ist, zu lösen.

Ich schlage vor, diese Anordnung:

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

Dann werden Sie in der Lage sein zu tun, Sachen wie:

my_project.main_category

my_category.optional_category_1_projects

# etc...

Andere Tipps

Vielleicht den Controller etwas ändern wie:

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

Sie müssen möglicherweise main_category_id in Ihrer Ansicht verwenden, d.

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

Du nennst update_attributes, aber main_category ist nicht richtig ein Attribut - es ist ein Verband ist. main_category_id ist ein Attribut.

Wo bekommen Sie @project aus? Sind Sie nur ein normales Project.find(params[:project_id]) oder etwas zu tun?

Versuche in einer debugger Aussage zu werfen und zu sehen, welche Klasse die @project ist und welche Methoden es hat auf sie?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top