When working with many-to-many relationships, I need to maintain a log file recording the changed values. Using the before_save and after_save callbacks works fine for the main (has_many) model itself but in the before_save callback the associated (belongs_to) records appear to be updated already! It seems rather odd to see that some parts of the data already have been updated before the 'before_save' callback is called.
Also, using callbacks in the associated model reveals that there is no before_destroy executed. Only the before_save gets called and shows the new values. I also tried the :prepend => :true option but that didn't gave other results.
When turning on SQL logging before the actual save in the main (has_many) model, I can see Rails is fetching the associated records, determines the differences and deletes the surplus record(s). The before_destroy of the associated model is not called. It then calls the before_save of the associated model and inserts the new ones (if any) and commits the transaction. This is all done JUST BEFORE the before_save of the main model.
Does anyone know how to fetch the associated records before they are changed? I would expect the before_destroy of the associated model would get called and let me handle it.
For clarity sake, lets give some extended information:
Changes to the Book record are perfectly logged. But there is no way to fetch the changed associated values for author_ids. A before_destroy callback in Title was not called, the after_save was.
I checked this with enabling the SQL logging just before the assignment of the new author_ids to the edited record. I could see that Rails determines the differences between the existing and new associated values, deletes the surplus form the Titles table and insert the extra ones (if any)
I solved it by moving the logging for the changes in Titles to the Books controller by comparing the old with the new values:
Like I said, it works but IMHO it does not reflect the Rails way of doing things. I would have expected to get the previous author_ids in the same way as any other Book attribute.