Предотвращение ActiveRecord сохраняет () на экземпляре

У меня есть объект модели ActiveRecord Foo; это представляет стандартную строку базы данных.

Я хочу смочь отобразить измененные версии экземпляров этого объекта. Я хотел бы снова использовать сам класс, поскольку он уже имеет все рычаги и аспекты, мне будет нужно. (Например: у Меня уже есть представление, которое отображает соответствующие атрибуты). В основном я хочу клонировать образцовый экземпляр, изменить некоторые его свойства и подать его назад вызывающей стороне (представление, тест, и т.д.).

Я не хочу эти модификации атрибута, возвращающиеся в базу данных. Однако я действительно хочу включать id атрибут в клонированной версии, поскольку это делает контакт с помощниками маршрута намного легче. Таким образом я планирую вызов ActiveRecord::Base.clone(), вручную устанавливая идентификатор клонированного экземпляра и затем внося соответствующие изменения атрибута в новый экземпляр. Это имеет меня, волновался хотя; один save() на измененном экземпляре и моих исходных данных будет ударен.

Так, я надеюсь блокировать вниз новый экземпляр так, чтобы он не повреждал ничто больше. Я уже - планирование вызова freeze() (на понимании, что это предотвращает дальнейшую модификацию к объекту, хотя документация не является ужасно четкой). Однако я не вижу очевидного способа предотвратить сохранение ().

Каков был бы лучший подход к достижению этого?

8
задан Craig Walker 30 May 2010 в 00:00
поделиться

2 ответа

freeze(), похоже, достигает того, чего я хочу, хотя и некрасивым способом.

x = Factory.create(:my_model)
x.save!    # true
x.freeze
x.save!
TypeError: can't modify frozen hash

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

Таким образом, замораживание предотвращает сохранение... но я был бы признателен за более надежный метод с более конкретным сообщением об ошибке.

4
ответ дан 5 December 2019 в 05:55
поделиться

Может быть более идиоматический способ сделать это, но один из способов - установить виртуальный атрибут и проверить его в обратном вызове before_save . Когда вы клонируете объект, установите виртуальный атрибут - например, is_clone на true . Затем определите обратный вызов before_save для вашего класса модели, который предотвращает сохранение, если этот атрибут установлен.

4
ответ дан 5 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: