Как выполнить update_attributes без фактического сохранения изменений

Возможный дубликат:
Rails update_attributes без сохранения?

По сути, я хочу сделать ActiveRecord "update_attributes", оставляя ActiveRecord в ожидании изменений. Есть ли способ сделать это? Читайте дальше, если вам интересно, почему я хотел бы этого.

У меня есть форма, состоящая из трех частей: статическая часть (текстовые поля, независимые друг от друга), набор выборок (увеличивается по мере заполнения записей) и раздел, показывающий влияние выборок на группу зависимых объектов. Изменение выбора требует двусторонней проверки на сервере, чтобы определить эффекты, и некоторые из них влияют на выбор для будущих выборов. Выборы моделируются как ассоциация has_many из базовой модели. Например (обратите внимание, что записи [] обозначают HTML-SELECT)

Include [section]
  Exclude [subsection]
  Exclude [subsection]
Include [section]
  Exclude [subsection]
...

Я настроил форму как типичную форму вложенных атрибутов. Когда выбор изменяется, я отправляю обратно поля с помощью AJAX, так что я получаю типичный хэш params (например, params[:basemodel][related_models_attributes][0][:field_name]). Я хотел бы поместить это в несохраненный ActiveRecord, чтобы партиалы, которые я уже использую для генерации частей исходной страницы, можно было использовать для генерации ответа JS (для этого я использую файл js.erb). Использование Basemodel.new(params[:basemodel]) дает ошибку

"ActiveRecord::RecordNotFound (Couldn't find AssociatedModel with ID=1 for Basemodel with ID=)

Это происходит (я думаю), потому что идентификаторы из существующих связанных записей (которые имеют непустые идентификаторы в текущей записи) не совпадают с пустыми идентификаторами, которые будут сгенерированы из "нового" вызова.

Я мог бы сделать что-то действительно грязное и создать что-то, похожее на ActiveRecord (по крайней мере, достаточно, чтобы оно соответствовало моим частям), но я должен думать, что это достаточно распространенная проблема, и для нее есть хорошее решение.

2 ответа

Решение

В зависимости от источника ActiveRecord::Persistence#update_attributes

# File activerecord/lib/active_record/persistence.rb, line 127
def update_attributes(attributes)
  # The following transaction covers any possible database side-effects of the
  # attributes assignment. For example, setting the IDs of a child collection.
  with_transaction_returning_status do
    self.attributes = attributes
    save
  end
end

Вы можете назначить атрибуты для вашей модели, используя

model.attributes = attributes

где атрибуты - это хэш полей модели и т. д.

Следующее должно, как update_attributesПозволяет вам передавать подмножество атрибутов модели, не очищая другие атрибуты, а также молча игнорировать любые неизвестные атрибуты в вашем хэше. Также не должно волновать, используете ли вы строки или символы в качестве ключей хеша.

def set_attributes (attributes)
  attributes.each do |key, value|
    self.send("#{key}=", value) if self.respond_to?("#{key}=")
  end
end
Другие вопросы по тегам