views:

79

answers:

3

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 when a field isn't changing? Or maybe I'm doing something wrong?

A: 
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.

Wojciech Kruszewski
+1  A: 

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
nowk
A: 

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%5Fvalidations%5Fcallbacks.html#callbacks-overview

Hope it helps.

Priyank
Thanks! Problem with callbacks is that it doesn't show errors even when I add them to error.add_to_base
klew