Использование сборки с помощью has_many :через
-
21-08-2019 - |
Вопрос
У меня есть Entry
модель и Category
модель, в которой Запись может иметь множество категорий (через 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
При создании новой записи я создаю ее, вызывая @journal.entries.build(entry_params)
, где entry_params
это параметры из формы ввода.Однако, если выбраны какие-либо категории, я получаю эту ошибку:
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.
Обратите внимание, что '#' во второй строке дословно;он не выводит объект.
Я попытался присвоить моим категориям поле выбора в форме, чтобы categories
и category_ids
но ни то, ни другое не имеет значения;если что-либо из этого есть в entry_params
, сохранение завершится неудачей.Если категории не выбраны, или я удаляю categories
От entry_params
(@entry_attrs.delete(:category_ids)
), сохранение работает должным образом, но категории, очевидно, не сохраняются.
Мне кажется, проблема в том, что запись EntryCategory пытается быть создана до того, как запись Entry будет сохранена?Разве build не должен позаботиться об этом?
Обновить:
Вот соответствующие части schema.rb, как и было запрошено:
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
Кроме того, сохранение записи с категориями отлично работает в действии обновления (путем вызова @entry.attributes = entry_params
), поэтому мне кажется, что проблема основана только на записи, не существующей на момент попытки создания записей EntryCategory.
Решение
Я выяснил, что причина этой ошибки кроется в nested_has_many_through
плагин.Похоже, что версия, которую я установил, была глючной;после обновления до самой последней версии моя сборка снова работает.
Другие советы
Зачем ты звонишь
self.journal.build(entry_params)
вместо того, чтобы
Entry.new(entry_params)
Если вам нужно создать новую запись, связанную с определенным журналом, указав @journal, вы можете сделать
@yournal.entries.build(entry_params)