Add additional update method which forces saved_change_to_attribute to return true

I’m writing a microservice (Service A) that relies heavily on one of the other services (Service B). Service B is a Ruby on Rails application. Both Service A and Service B share a db. Service A receives a request and updates a table in the db. When Service B receives that same request, it uses ActiveRecord and a lot of callbacks on the AR model. Rather than spreading the same business logic between services, I’d like to event that request to Service B. This way, Service B can “update” the model (the word “update” is in parentheses because the services share the same db and the record is already updated) and trigger all of the callbacks.

For example, assume a request is made to Service A to update the name of a user. Service A updates the user’s name in the db, and then events this change to Service B. Service B receives the request and does something similar to the following:

user = User.find(id: user_id)

user.update_attribue(:name, name)

This triggers ActiveRecord callbacks on the User model. In one of the callbacks, the following conditional statement is made: saved_change_to_name?. This returns false because the record wasn’t actually updated since Service A already updated the db.

Is it possible to force this change and have saved_change_to_name? result in true? For example:

user = User.find(id: user_id)

user.force_update_attribue(:name, name)

Using update_attribute will update the db, but ActiveRecord tells the user that the attribute was only updated if the attribute changed. This feature request is to add an additional update method (or modify an already existing update method) to indicate that the attribute was updated even if its value didn’t change.

Service A still needs to update the db because we’re moving towards an approach where each service has its own data store. Removing the conditional is also not an option here.

One of the big problems you’re going to run into here is that the nothing actually gets persisted in the DB the second time in this scenario. If the value of your name attribute isn’t different from what’s already in the database when you call update_attribute, then nothing gets persisted and the updated_at timestamp doesn’t get touched. Therefore, no change is recorded to ActiveModel to return. Why not just manually invoke the callback chain if the value in memory matches the model retrieved from the DB?