Is there an easy way to make a Rails ActiveRecord model read-only?

I want to be able to create a record in the DB but then prevent Rails from making changes from that point on. I understand changes will still be possible at the DB level.

I believe attr_readonly does what I want on an attribute level, but I don't want to have to manually specify fields... I would rather have more of a white-list approach.

Also, I know there is a :read_only option for associations, but I don't want to limit the "readonlyness" of the object to if it was fetched via an association or not.

Finally, I want to be able to still destroy a record so stuff like :dependent => :destroy works in the associations.

So, to summarize: 1) allow the creation of records, 2) allow the deletion of records, and 3) prevent changing records that have been persisted.


Solution 1:

Looking at ActiveRecord::Persistence, everything ends up calling create_or_update behind the scenes.

def create_or_update
  raise ReadOnlyRecord if readonly?
  result = new_record? ? create : update
  result != false
end

So! Just:

def readonly?
  !new_record?
end

Solution 2:

I've found a more concise solution, which uses the after_initialize callback:

class Post < ActiveRecord::Base
  after_initialize :readonly!
end