ActiveRecord Read Only Model
ActiveRecord is great in providing CRUD for your data models. In some cases, however, it’s necessary to prevent write access to these models. The data may be provided by an external source and should only be used as a reference in your application, for example.
I’m going to show you how you can easily mark a Model as read only all the time. In this example I have a Item model like this:
class Item < ActiveRecord::Base end
ActiveRecord::Base provides two methods that may be of interest here:
def readonly! @readonly = true end def readonly? defined?(@readonly) && @readonly == true end
The first method sets the record to read only. This is great, but we don’t want to set the read only property every time we load a model. The second, readonly?, return true if the object is read only or false if it isn’t.
So, if we return true on the readonly? method, our object is marked as read only. Great!
class Item < ActiveRecord::Base def readonly? true end end
That is all! All Item objects are now marked as read only all the time. If you try to write to the model, you’ll receive an error.
item = Item.find(:first) item.update_attributes(:name => 'Some item name') => ActiveRecord::RecordReadOnly
Hey Mathijs,
As I mentioned in the post, sometimes you want to access data from your app that you don’t want changed under any circumstance.
There are several ways this might happen accidentily, but the most common situation would be a programmers mistake. If you’re working with a lot of different developers on the same project it’s easy to ‘forget’ that you can’t update these models.
Of course, it’s better not to call update methods at all. Still, as a safety net, marking these objects readonly sounds like a better solution than overriding the update method.
Errors and exceptions are not scary things ;-)















Can you tell me about a real case where you’ve needed read-only models? I’ve never needed it. And I don’t see a reason for it.
ActiveRecord raisen an ActiveRecord::ReadOnlyRecord exception when you try to update a read-only model. That means you’ve already made a mistake by calling that update function. You could rescue that exception, but it also possible to just not send that update message.