L'utilisation construire avec has_many: par
-
21-08-2019 - |
Question
J'ai un modèle et un modèle Entry
Category
, où une entrée peut avoir plusieurs catégories (par EntryCategories
):
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ù les paramètres est entry_params
du formulaire d'inscription. 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 fait un objet ne sort pas.
Je l'ai essayé de nommer mes catégories selectbox sur le formulaire et categories
mais ni category_ids
faire une différence; si l'une est dans le @entry_attrs.delete(:category_ids)
, la sauvegarde échouera. Si aucune catégorie sont sélectionnés, ou je supprimer de @entry.attributes = entry_params
<=> (<=>), la sauvegarde fonctionne correctement, mais les catégories ne sauvegardons pas, é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 être construire en prenant 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 <=>), il me semble que le problème ne repose que sur l'entrée non existante au point que les dossiers de EntryCategory sont tentées à créer.
Autres conseils
Pourquoi appelez-vous
self.journal.build(entry_params)
au lieu de
Entry.new(entry_params)
Si vous avez besoin pour créer une nouvelle entrée associée à un journal spécifique, donné une @journal, vous pouvez faire
@yournal.entries.build(entry_params)