1

I have a model callback like this:

after_save :foobar, except: :create

The code this runs is mostly irrelevant to the model itself, so I wish to move it into an observer. I find I can do something like this:

def after_save(model)
  foobar(model)
end

However, this does not maintain the except: :create behavior of my callback, which is very important in this instance.

Is it possible to use callback conditionals such as except in a Rails observer? If so, how would I go about doing so?

slondr
  • 201
  • 3
  • 10
  • You're going to have do define what you mean by "Rails observer" as it was removed from the core in Rails 4. Are you talking about the Rails::Observers gem? – max Sep 09 '21 at 14:13
  • @max Yes, I'm talking about the now-gem previously part of rails core. – slondr Sep 09 '21 at 14:18
  • Is this legacy code or why do you think observers are a good answer to your given problem? – max Sep 09 '21 at 14:20
  • @max I believe observers are a good answer to my problem because the code in question is updating attributes of many records and should be run after certain records are saved. As I said in the question, currently I have this written as a callback in the model, which seems wrong to me because the code doesn't actually do anything with the "current" record it runs in, hence my desire to switch the code to an observer. – slondr Sep 09 '21 at 14:26
  • 4
    Sorry if this sounds like kneejerk contrarianism, but there is a reason why they fell by the wayside and other alternatives like service objects that do the job better. https://stackoverflow.com/questions/15165260/rails-observer-alternatives-for-4-0 – max Sep 09 '21 at 14:27
  • @max Are those reasons relevant to my question here? Do you have information for why abandoning the gem I'm already using would be the best path to solve this problem? – slondr Sep 09 '21 at 14:36
  • Its up to you to decide if its relevant to the particular question here but it definely ties in. Observers just like model callbacks are implicit instead of expliclit like calls to service objects. While it may intially seem like a convenient solution it becomes increasingly complex to handle when and where your callbacks/observers are fired as the complexity of your application grows. But of course do as you want. – max Sep 09 '21 at 16:45

1 Answers1

1

when you define

after_save :foobar, except: :create

it means that you only trigger the callback for update, so just define in your observer:

def after_update(model)
  # do something here
end
Les Nightingill
  • 5,662
  • 1
  • 29
  • 32
  • Excellent, that is precisely what I was looking for. I hadn't made the connection between when my callback was actually running and other lifecycle events that might correspond to. Thank you! – slondr Sep 09 '21 at 18:36