In ActiveRecord how do I use 'changed' (dirty) in a before_save callback?
activerecord, ruby-on-rails
Solution
Your controller probably saves twice as said by @nasmorn. You can also check that your body as changed before updating your summary.
if self.body_changed? && (!self.summary_changed? or self.summary.blank?)
self.summary = Sanitize.clean(self.body).to(255)
end
Problem
I want to set my summary field to a sanitized version of the body field, but only if the user does not supply their own summary ie. params[:document][:summary] is blank. This appears to work fine if I create a new record, if I enter a summary it is saved, if I don't the body is used to generate the summary. However when I update the record the summary always gets overridden. From my log files I can see that 'generate_summary' gets called twice, the second time the 'changes' hash is empty. ``` class Document << ActiveRecord::Base # Callbacks before_save :generate_summary private def generate_summary @counter ||= 1 logger.debug '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' logger.debug @counter.to_s logger.debug 'changes: ' + self.changes.inspect self.summary = Sanitize.clean(self.body).to(255) if self.body && (!self.summary_changed? or self.summary.blank?) @counter = @counter + 1 end ``` Log on Update: $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 1 changes: {"summary"=>["asdasdasdasd", "three.co.uk"]} Page Update (0.7ms) UPDATE `documents` SET `meta_description` = 'three.co.uk', `summary` = 'three.co.uk', `updated_at` = '2009-09-30 11:37:08' WHERE `id` = 77 SQL (0.6ms) COMMIT SQL (0.1ms) BEGIN $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 2 changes: {} Page Update (0.5ms) UPDATE `documents` SET `meta_description` = 'asdasdasdasd', `summary` = 'asdasdasdasd', `updated_at` = '2009-09-30 11:37:08' WHERE `id` = 77