I work at a large company with a somewhat large Ruby on Rails application. We have internally debated how to handle event callbacks (e.g. Model 1 changes from state A -> B, how should Model 2 "find out").
In our codebase, we've implemented a few different approaches. We'd like to consolidate on a single approach. We're curious what companies with even larger / more mature Rails applications have gone with (e.g. what have the Stripes and Shopifys of the world done).
The approaches currently used in our codebase are:
- Observers (which I see were apparently removed from Rails in 4.0)
- Commands, which are basically functions that encapsulate a series of state changes across multiple models. In this approach, we ban models from directly calling one another (and instead only allow calling model functions from the top-level command). So a command might look like
Model1.do_a; Model2.do_b; Model3.do_c
. - Callback functions (e.g.
on_a
) on models themselves.
For what it's worth, some of the problems we've observed with each approach are:
- Observers: Because these are "implicit," they are not as discoverable. At times, these have been a footgun (make it easy to accidentally trigger dangerous callback by accident).
- Commands: This approach seems more non-standard but so far these have led to less bugs.
- Callback functions: These have also at times been a footgun because they make it possible accidentally introduce circular callbacks (e.g. Model 1 calls
on_a
on Model 2, Model 2 callson_b
on Model 3, Model 3 callson_c
on Model 1).