has_many durch Update-Problem
-
23-08-2019 - |
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
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?