james james - 2 months ago 8
Ruby Question

Rails - attribute that has not changed has registered as changed?

Order has_many RentalItems


So I have this callback on
Order
where the point is that the
xyz_method
runs whenever any child
RentalItem
has its
size
or
specification
changed, or a new child
RentalItem
has been added.

before_save do
if rental_items_attributes_modified?
xyz_method
end
end

def rental_items_attributes_modified?
self.rental_items.each do |ri|
# as long as ONE item had ONE thing changed, we return true or it's a new record
puts "in RI modified?"
puts "#{ri.new_record?} with ID #{ri.id}"
puts "#{ri.specification_changed?} from #{ri.specification_was} to #{ri.specification}"
puts "#{ri.size_changed?} from #{ri.size_was} to #{ri.size}"
if ri.specification_changed? || ri.size_changed? || ri.new_record?
return true
end
end
return false
end


All the
puts
were helping me debug... I have no idea why but
rental_items_attributes_modified?
keeps returning true, because for ONE of the
RentalItems
, the
specification_changed?
returns
true
even though it's not... This is the relevant log output:

# testing the first child RI
in RI modified?
false with ID 1
false from blue to blue
false from Regular to Regular

# testing the second child RI
in RI modified?
false with ID 2
true from to # <<< why is this happening???
false from Regular to Regular


For the weird second child
RI
in question,
specification = ""
initially, and what gets passed are params like this:

"rental_items_attributes"=>[{"id"=>"2", "specification"=>"", "size"=>"Regular"}]


I have tried this standalone in the console, and it triggers the correct behavior...

# for an order whose child RI initially had a blank specification & size
o.update_attributes({"rental_items_attributes" => [{"id" => 79, "specification" => ""}]})
=>
in RI modified?
false with ID 79
false from to
false from to

Answer

It's just a comment, but I can't write a comment due to less reputation. (Thus, you can ignore this comment.)

Have you ever checked values in before_save block? Like,

ri.specification_was.nil?
ri.specification.nil?

Both are false?