views:

144

answers:

1

Does Rail's ActiveRecord have any special rules when attempting to set one of the column values in the model to nil?

The sanity check in the method freez always fails.

Model: Project

Column: non_project_costs_value (nullable decimal field)

def froz?
    return !(non_project_costs_value.nil?)
end


def freez(val)
    raise 'Already frozen, cannot freeze ... the value is ' + non_project_costs_value.to_s if froz?
    non_project_costs_value = val
    save
    raise 'Sanity check.  After freezing the thing should be frozen!' if !froz?
end
+1  A: 

You have a bug in your freez method

non_project_costs_value = val # this is setting a local variable
                              # (in the method freez) to val

# change to:
self.non_project_costs_value = val # this will set the record's attribute
                                   # (the column) to val
                                   # It will be saved to the dbms once you save
Larry K
Would that mean I also have a bug in my 'froz?' method? There I use non_project_costs_value and not self.non_project_costs_value.
Daniel
No. The reason is that there is no local var named non_project_costs_value in your froz? method. So Ruby looks for a method non_project_costs_value. It doesn't find one, but the ActiveRecord machinery overrides the "no method found" function, notices that the method wanted (non_project_costs_value) is an attribute, and then supplies the value. But if you define non_project_costs_value as a local variable (by assigning to it) then later ref to non_project_costs_value (in same name scope) will use the local var. The docs discuss this, but I couldn't find a good ref just now. See doc for AR base
Larry K