2009-06-29 9 views
1

J'ai un modèle Entry et un modèle Category, où une entrée peut avoir plusieurs catégories (par EntryCategories):Utilisation de construire avec has_many: par

class Entry < ActiveRecord::Base 
    belongs_to :journal 

    has_many :entry_categories 
    has_many :categories, :through => :entry_categories 
end 

class Category < ActiveRecord::Base 
    has_many :entry_categories, :dependent => :destroy 
    has_many :entries, :through => :entry_categories 
end 

class EntryCategory < ActiveRecord::Base 
    belongs_to :category 
    belongs_to :entry 
end 

Lors de la création d'une nouvelle entrée, je crée en appelant @journal.entries.build(entry_params) , où entry_params sont les paramètres de la forme d'entrée. Si les catégories sont sélectionnées, cependant, je reçois cette erreur:

ActiveRecord::HasManyThroughCantDissociateNewRecords in Admin/entriesController#create 

Cannot dissociate new records through 'Entry#entry_categories' on '#'. Both records must have an id in order to delete the has_many :through record associating them. 

Notez que le « # » sur la deuxième ligne est mot pour mot; il ne sort pas un objet.

J'ai essayé de nommer mes catégories selectbox sur le formulaire à categories et category_ids mais aucune ne fait de différence; Si l'une des deux est dans le entry_params, l'enregistrement échouera. Si aucune catégorie n'est sélectionnée, ou que je supprime categories de entry_params (@entry_attrs.delete(:category_ids)), la sauvegarde fonctionne correctement, mais les catégories ne sont pas sauvegardées, évidemment.

Il me semble que le problème est qu'un enregistrement EntryCategory tente d'être fait avant que l'enregistrement d'entrée est enregistré? Ne devrait pas construire prendre soin de cela?

Mise à jour:

Voici les parties pertinentes de schema.rb, comme l'a demandé:

ActiveRecord::Schema.define(:version => 20090516204736) do 

    create_table "categories", :force => true do |t| 
    t.integer "journal_id",         :null => false 
    t.string "name",  :limit => 200,     :null => false 
    t.integer "parent_id" 
    t.integer "lft" 
    t.integer "rgt" 
    end 

    add_index "categories", ["journal_id", "parent_id", "name"], :name => "index_categories_on_journal_id_and_parent_id_and_name", :unique => true 

    create_table "entries", :force => true do |t| 
    t.integer "journal_id",           :null => false 
    t.string "title",            :null => false 
    t.string "permaname", :limit => 60,       :null => false 
    t.text  "raw_body", :limit => 2147483647 
    t.datetime "created_at",           :null => false 
    t.datetime "posted_at" 
    t.datetime "updated_at",           :null => false 
    end 

    create_table "entry_categories", :force => true do |t| 
    t.integer "entry_id", :null => false 
    t.integer "category_id", :null => false 
    end 

    add_index "entry_categories", ["entry_id", "category_id"], :name => "index_entry_categories_on_entry_id_and_category_id", :unique => true 

end 

En outre, l'enregistrement d'une entrée des catégories fonctionne très bien dans l'action de mise à jour (en appelant @entry.attributes = entry_params), Il me semble donc que le problème est uniquement basé sur l'entrée n'existe pas au moment où les enregistrements EntryCategory sont tentés d'être créés.

+0

Pourriez-vous joindre la définition schema.rb? –

Répondre

2

J'ai recherché la cause de cette erreur dans le plug-in nested_has_many_through. Il semble que la version que j'avais installée était buggée; après la mise à jour vers la version la plus récente, ma construction fonctionne à nouveau.

1

Pourquoi appelez-vous

self.journal.build(entry_params) 

au lieu de

Entry.new(entry_params) 

Si vous avez besoin donné une @journal, créer une nouvelle entrée associée à un journal spécifique, vous pouvez faire

@yournal.entries.build(entry_params) 
+1

C'est en fait @ journal.entries.build, j'ai foiré en tapant la question, merci de le signaler. –

Questions connexes