How to set some field in model as readonly when a condition is met?
I have models like this:
class Person
has_many :phones
...
end
class Phone
belongs_to :person
end
I want to forbid changing phones associated to person when some condition is met. Forbidden field is set to disabled
in html form. When I added a custom validation to check it, it caused save error even when phone doesn't change. I think it is because a hash with attributes is passed to
@person.update_attributes(params[:person])
and there is some data with phone number (because form include fields for phone). How to update only attributes that changed? Or how to create validation that ignore saves whe开发者_如何学运维n a field isn't changing? Or maybe I'm doing something wrong?
You might be able to use the
changed # => []
changed? # => true|false
changes # => {}
methods that are provided.
The changed
method will return an array of changed attributes which you might be able to do an include?(...)
against to build the functionality you are looking for.
Maybe something like
validate :check_for_changes
def check_for_changes
errors.add_to_base("Field is not changed") unless changed.include?("field")
end
def validate
errors.add :phone_number, "can't be updated" if phone_number_changed?
end
-- don't know if this works with associations though
Other way would be to override update_attributes, find values that haven't changed and remove them from params hash and finally call original update_attributes.
Why don't you use before_create, before_save callbacks in model to restrict create/update/save/delete or virtually any such operation. I think hooking up observers to decide whether you want to restrict the create or allow; would be a good approach. Following is a short example.
class Person < ActiveRecord::Base
#These callbacks are run every time a save/create is done.
before_save :ensure_my_condition_is_met
before_create :some_other_condition_check
protected
def some_other_condition_check
#checks here
end
def ensure_my_condition_is_met
# checks here
end
end
More information for callbacks can be obtained here: http://guides.rubyonrails.org/activerecord_validations_callbacks.html#callbacks-overview
Hope it helps.
精彩评论