Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing ActiveRecord save() on an instance

I have an ActiveRecord model object Foo; it represents a standard database row.

I want to be able to display modified versions of instances of this object. I'd like to reuse the class itself, as it already has all the hooks & aspects I'll need. (For example: I already have a view that displays the appropriate attributes). Basically I want to clone the model instance, modify some of its properties, and feed it back to the caller (view, test, etc).

I do not want these attribute modifications getting back into the database. However, I do want to include the id attribute in the cloned version, as it makes dealing with the route-helpers much easier. Thus, I plan on calling ActiveRecord::Base.clone(), manually setting the ID of the cloned instance, and then making the appropriate attribute changes to the new instance. This has me worried though; one save() on the modified instance and my original data will get clobbered.

So, I'm looking to lock down the new instance so that it won't hurt anything else. I'm already planning on calling freeze() (on the understanding that this prevents further modification to the object, though the documentation isn't terribly clear). However, I don't see any obvious way to prevent a save().

What would be the best approach to achieving this?

like image 323
Craig Walker Avatar asked May 30 '10 00:05

Craig Walker


People also ask

Can you use ActiveRecord without rails?

One of the primary aspects of ActiveRecord is that there is very little to no configuration needed. It follow convention over configuration. ActiveRecord is commonly used with the Ruby-on-Rails framework but you can use it with Sinatra or without any web framework if desired.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.

What does ActiveRecord base mean?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.


2 Answers

You can use ActiveRecord::Base#readonly!

model = MyModel.find 1
model.readonly!
model.save!

it will raise ActiveRecord::ReadOnlyRecord

like image 193
Reynard Avatar answered Sep 20 '22 06:09

Reynard


There might be a more idiomatic way to do this, but one way would be to set a virtual attribute and check it in a before_save callback. When you clone the object, set the virtual attribute – maybe something like is_clone to true. Then define a before_save callback for your model class that prevents the save if that attribute is set.

like image 45
Jimmy Avatar answered Sep 23 '22 06:09

Jimmy