I've been preventing updates to certain models by using this in the model:
def update
self.errors.add_to_base( "Cannot update a #{ self.to_s }" )
end
I'm now writing a plugin that delivers some extra functionality to the model, and I need to update one field in the model. If I weren't using a plugin I would do this directly in the model...
def update
if self.changed == ['my_field']
super
else
self.errors.add_to_base( "Cannot update a #{ self.to_s }" )
end
end
I can't do the same from my plugin since I don't know if the update behaviour is the ActiveRecord default, or has been overridden to prevent updates. Is there another way to prevent record updates while allowing me to override for a specific field (and only in the instance where my plugin is applied to this model).
First, you should be using a before_update callback for that sort of thing rather than overriding update. Second, you can store the updatable attributes on the model, and then update them with the plugin. I just wrote this in the browser, so it could be wrong.
attr_accessor :updatable_attributes
before_update :prevent_update
private
def prevent_update
return true if self.changed == self.updatable_attributes
self.errors.add_to_base "Cannot update a #{ self.to_s }"
false
end
end
Late to the game here, but for people viewing this question, you can use attr_readonly
to allow writing to a field on create, but not allowing updates.
See http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html
I think it has been available since Rails 2.0
The tricky part is, if you have any attributes that are attr_accessible
you have to list your read only attributes there also (or you get a mass assignment error on create):
class Post < ActiveRecord::Base
attr_readonly :original_title
attr_accessible :latest_title, :original_title
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With