Implementing conditional read-only attributes of ActiveRecord objects


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? :wink: Maybe somebody with more Rails plugin experience ...