# Implementing conditional read-only attributes of ActiveRecord objects

**URL:** <https://www.ruby-forum.com/t/implementing-conditional-read-only-attributes-of-activerecord-objects/161827>\
**Category:** Rails\
**Created:** [March 2, 2009, 9:49pm UTC](https://www.ruby-forum.com/t/implementing-conditional-read-only-attributes-of-activerecord-objects/161827 "2009-03-02T21:49:04Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jens](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/d2c977/32.png) [@jens](https://www.ruby-forum.com/u/jens)\
**Post date:** [March 2, 2009, 9:49pm UTC](https://www.ruby-forum.com/t/implementing-conditional-read-only-attributes-of-activerecord-objects/161827/1 "2009-03-02T21:49:04Z")

</div>

Hello,

my goal is to implement the option of specifying a condition in  
attr\_protected, attr\_readonly and possibly other attribute methods in  
ActiveRecord objects.

Rationale (example):

class User \< AR:Base

# User should not be able to modify fields any more once they have

been verified  
attr\_readonly :firstname, :lastname, :gender\_id, :birthdate, :if  
=\> :passport\_verified?

# …

end

or, even better yet, attr\_protected with the same options, since this  
will allow an admin controller to directly write the attributes while  
the “normal” user forms will just ignore them.

The “:if” option should, like in validations, accept a Proc, String,  
Symbol or anything the calling object responds to. For validations,  
this is currently implemented in activesupport/callbacks.rb in  
evaluate\_method(), unfortunately in a private method, so we cannot  
just call this method.

The idea is that I can tell my custom FormBuilder to check for a  
readonly flag on an AR instance object’s attribute, and set the  
respective form field to “disabled”, so the user experience is  
consistent. This, however, requires that the readonly state is  
determined on object _creation_ (or load time) and not only when  
validation happens.  
So the approach used in “attr\_readonly” doesn’t work since it’s a  
class method.

I could of course, do something like

ReadonlyAttributes = [:firstname, :lastname, :gender\_id, :birthdate]  
def is\_readonly?(attr)  
true if ReadonlyAttributes.include?(attr) and  
self.passport\_verified?  
end  
def validate  
ReadonlyAttributes.each do |attr|  
errors.add(attr, “You cannot change #{attr}!”) if attr.changed?  
end  
end

only that “changed?” in this context would probably not work since the  
object in question would not be “changed”, but newly created from a  
params Array.

But also IMHO, this concept should IMHO be extracted into a plugin.  
Something like

acts\_as\_readonly\_if :firstname, :lastname, :gender\_id, :birthdate, :if  
=\> :passport\_verified?

which would define is\_readonly? and extend the validations.

My questions are -

- does this make any sense?
- has anything like this perhaps already been done (and if so, where)?
- would anybody like to help? 😉 Maybe somebody with more Rails plugin  
experience …

Thanks!

Jens
