Использование сборки с has_many: through - PullRequest
1 голос
/ 30 июня 2009

У меня есть модель 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? Не стоит ли строить заботиться об этом?

Обновление:

Вот соответствующие части 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. быть созданным.

Ответы [ 2 ]

2 голосов
/ 30 июня 2009

Я обнаружил причину этой ошибки в плагине nested_has_many_through. Кажется, что версия, которую я установил, была глючной; после обновления до последней версии моя сборка снова работает.

1 голос
/ 30 июня 2009

Почему вы звоните

self.journal.build(entry_params)

вместо

Entry.new(entry_params)

Если вам нужно создать новую запись, связанную с конкретным Журналом, с учетом @journal, вы можете сделать

@yournal.entries.build(entry_params)
...