Utilizzando costruire con has_many: attraverso
-
21-08-2019 - |
Domanda
Ho un modello Entry
e un modello Category
, in cui una voce può avere molte categorie (tramite 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
Quando si crea una nuova voce, creo chiamando @journal.entries.build(entry_params)
, dove entry_params
sono i parametri del modulo di iscrizione. Se nessuna categoria sono selezionati, tuttavia, ottengo questo errore:
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.
Si noti che il '#' sulla seconda riga è testualmente; esso non emette un oggetto.
Ho cercato di denominazione mie categorie selectbox sul modulo per categories
e category_ids
ma né fare la differenza; se uno dei due è in @entry_attrs.delete(:category_ids)
, il salvataggio falliranno. Se non ci sono categorie sono selezionati, o tolgo @entry.attributes = entry_params
da <=> (<=>), il salvataggio funziona correttamente, ma le categorie non si salva, ovviamente.
Mi sembra che il problema è che un record EntryCategory sta cercando di essere fatto prima che il record di ingresso è salvato? Non dovrebbe essere costruire prendersi cura di questo?
Aggiornamento:
Ecco le parti pertinenti delle schema.rb, come richiesto:
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
Inoltre, risparmiando una voce con le categorie funziona bene nell'azione di aggiornamento (chiamando <=>), in modo che non mi sembra che il problema si basa solo sulla voce non esistente nel punto in cui i record vengono tentate EntryCategory da creare.
Soluzione
Ho rintracciato la causa di questo errore di essere all'interno della nested_has_many_through
plugin. Sembra che la versione avevo installato era bacato; dopo l'aggiornamento alla versione più recente, la mia costruzione funziona di nuovo.
Altri suggerimenti
Perché si chiama
self.journal.build(entry_params)
anziché
Entry.new(entry_params)
Se avete bisogno di creare una nuova voce associata ad una specifica ufficiale, dato un @journal, si può fare
@yournal.entries.build(entry_params)