I have a custom accessor method in my rails 3.1.6 app that assigns a value to an attribute, even if the value is not present.The my_attr attribute is a serialized Hash which should be merged with the given value unless a blank value is specified, in which case it will set the current value to a blank value. (There are added checks to make sure the values are what they should be, but are removed for brevity, as they are not part of my question.) My setter is defined as:
def my_attr=(new_val)
cur_val = read_attribute(:my_attr) #store current value
#make sure we are working with a hash, and reset value if a blank value is given
write_attribute(:my_attr, {}) if (new_val.nil? || new_val.blank? || cur_val.blank?)
#merge value with new
if cur_val.blank?
write_attribute(:my_attr, new_val)
else
write_attribute(:my_attr,cur_val.deep_merge(new_val))
end
read_attribute(:my_attr)
end
This code works well as-is, but not when I use self.write_attribute(). I then get the following error:
NoMethodError:
private method `write_attribute' called for #<MyModel:0x00000004f10528>
My questions are thus: It seems more logical to have write_attribute available to an instance, so why is it only available to the class and not to the instance? Is there something lacking in my fundamental knowledge of self in Ruby or Rails (or both)?