0

When changing a model's attributes in the controller's update, I want to generate a history of changes that are about to be made. For that, I've created a method generate_history to access from the instance.

The class:

class Assist < ActiveRecord::Base
    belongs_to: status

    def generate_history
        #Also tried without self

        p 'Testing round two'
        p 'Status' + self.status.id.to_s
        p 'Modified: ' + self.status.id_changed?.to_s
        p 'Old value ' + self.status.id_was.to_s

        #do something something dark side
    end

end

The issue is within that method, the ActiveModel::Dirty isn't aware of the changes that have been made, although the self.status_id's value is the new one.

Meanwhile in the controller:

def update

    ...

    @assist.assign_attributes(assist_params)

    p 'Testing round one'
    p 'Status' + @assist.status_id.to_s
    p 'Modified: ' + @assist.status_id_changed?.to_s
    p 'Old value ' + @assist.status_id_was.to_s

    p 'Generating history'

    @assist.generate_history

    p 'Testing round three'
    p 'Status' + @assist.status_id.to_s
    p 'Modified: ' + @assist.status_id_changed?.to_s
    p 'Old value ' + @assist.status_id_was.to_s
end

At first I was suspicious of assign_attributes that somehow interfered with ActiveModel::Dirty but I've realized that ActiveModel::Dirty works in the controller, where the values are being modified, but not when I'm calling generate_history.

Am I doing something wrong from within the instance method or its the way ActiveModel::Dirty works?

Example of output:

Testing round one
Status 1
Modified: true
Old value 2

Generating history
Testing round two
Status 1
Modified: false
Old value 1

Testing round three
Status 1
Modified: true
Old value 2
Jaime Mendes
  • 643
  • 3
  • 9
  • Have you tried looking for the 'dirtiness' through the `status` attribute? Instead of `.status_id`, try `.status.id` and `.status_changed?`. It might work... – mr rogers Nov 29 '14 at 21:08
  • @mr-rogers `.status.changed?` reports false within the method – Jaime Mendes Nov 29 '14 at 22:12
  • sad. well, worth a try. – mr rogers Nov 29 '14 at 22:19
  • @mr-rogers Actually, you are right. I had within the generate_history method the .status.id and .status.id.changed? (which reported no modificaitons) while I was testing the output of .status_id.changed? in the controller. Can you put that as answer? – Jaime Mendes Nov 29 '14 at 22:24
  • Sure. glad that helped. Let me know if the answer posted matches what you got working. I was spitballing... – mr rogers Nov 29 '14 at 22:59

1 Answers1

0

My guess is that the status_id is not an attribute that is fully tracked by ActiveRecord::Dirty. Instead of looking at status_id, i think you should look at status. Something like:

class Assist < ActiveRecord::Base
    belongs_to: status
    def generate_history
        p 'Testing round two'
        p 'Status' + status_id.to_s
        p 'Modified: ' + status_id_changed?.to_s
        p 'Old value ' + status_id_was.to_s

        #do something something dark side
    end
end

Then your controller code is right.

And because you're not assigning status but only asking about it, you probably don't need the self.

mr rogers
  • 3,200
  • 1
  • 19
  • 31
  • Actually, is the other way around. status_id was the actual field being updated as it came from the params – Jaime Mendes Nov 29 '14 at 23:05
  • Got it. I just tried it on one of my projects and saw the difference. The dots and underscores are slippery suckers. – mr rogers Nov 29 '14 at 23:12