2010-05-30 1 views
5

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

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

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

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

Что было бы лучшим подходом к достижению этого?

+1

Если вам нужно возиться, что значительно со стандартным объектом ActiveRecord, есть, вероятно, лучший способ подхода к проблеме. – Matchu

+0

Я, безусловно, открыт для альтернатив –

ответ

4

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

4

freeze(), кажется, достигает того, чего хочу, хотя и уродливо.

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

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

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

+2

Просто для уточнения, замораживание предотвратит изменение экземпляра вообще, а только для чтения! позволят изменять, но предотвращать сохранение измененного экземпляра в базе данных. –

+0

Спасибо за обновление @DavidAldridge; Я изменил принятый ответ. –