Sherwin Yu
Sherwin Yu

Reputation: 3230

Rails ActiveRecord conditionally protect an attribute from modification

I have a Message model with a content attribute (string) and a sent attribute (boolean). A message's content should be modifiable until it's been sent, after which that field should become read only. (Other attributes can still be modifiable, such as message_opened).

How can I accomplish this? I've looked into overriding readonly? (only applies at the record level), attr_readonly (not conditional), and validations (don't know how to make the validation of the content depend on both its old value and the sent field).

Upvotes: 2

Views: 1685

Answers (2)

JAR.JAR.beans
JAR.JAR.beans

Reputation: 10034

Going over possible answers, I think setting the field as:

attr_readonly

Is the best option is it will totally protect that field without custom code needed.

Attributes listed as readonly will be used to create a new record but update operations will ignore these fields.

Upvotes: 0

Sherwin Yu
Sherwin Yu

Reputation: 3230

Turns out validations are the right approach: create a custom validation that uses attribute_changed? ("attribute" is the name of the attribute, in this case, "content") and a conditional validation.

Message.rb:

validate_on_update :reject_modifying_content, if: :sent?

def reject_modifying_content
 errors[:content] << "can not be changed!" if self.content_changed?
end

See Rails 3 check if attribute changed, Setting a field to read-only in Rails after it's created and http://api.rubyonrails.org/classes/ActiveModel/Dirty.html for more information.

Upvotes: 3

Related Questions