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?
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.
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.
ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.
You can use ActiveRecord::Base#readonly!
model = MyModel.find 1
model.readonly!
model.save!
it will raise ActiveRecord::ReadOnlyRecord
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With