Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 696
brettish Avatar asked Apr 12 '11 20:04

brettish


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's the purpose of ActiveRecord?

Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database. It is an implementation of the Active Record pattern which itself is a description of an Object Relational Mapping system.

What is ActiveRecord :: Base in Rails?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending. Edit: as Mike points out, in this case ActiveRecord is a module... ActiveRecord is defined as a module in Rails, github.com/rails/rails/tree/master/activerecord/lib/…


2 Answers

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 
like image 193
scragz Avatar answered Sep 19 '22 15:09

scragz


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

class Post < ActiveRecord::Base   after_initialize :readonly! end 
like image 30
kwarrick Avatar answered Sep 20 '22 15:09

kwarrick