Rails, callbacks, workers, and the race you never expected to lose
11–20 of 28 posts
Re: Rails, callbacks, workers, and the race you never expected to lose
#12Emails are like async views. The model should not be responsible for rendering views. That's the responsibility of the controller. Which is why Action Mailer itself is modelled on Action Controller, uses Action View, and so forth.
Re: Rails, callbacks, workers, and the race you never expected to lose
#13For this and related predictability/absence-of-surprise reasons, I have generally moved away from ActiveRecord callbacks in my Rails projects. It's very easy to forget that you e.g. have an after_save defined for accounts which made sense when accounts necessarily represented people with credit cards in the system but doesn't make sense for e.g. people paying via purchase order. It is also easy to forget an after_sav…
Absolutely agreed - better to make these things explicit somewhere rather than having your business logic implicitly handled by something directly coupled to your persistence layer (with the exception of data integrity tasks as mentioned by danenania). As a sort of half-way house between using lifecycle callbacks and sticking everything in the controller, I've just moved the main app I work on to a pub-sub event syst…
Re: Rails, callbacks, workers, and the race you never expected to lose
#14For this and related predictability/absence-of-surprise reasons, I have generally moved away from ActiveRecord callbacks in my Rails projects. It's very easy to forget that you e.g. have an after_save defined for accounts which made sense when accounts necessarily represented people with credit cards in the system but doesn't make sense for e.g. people paying via purchase order. It is also easy to forget an after_sav…
Agreed, I've come to view callbacks as a tool to enforce application-level data integrity and relationships, not a place that higher level business logic should live. The line is often fuzzy, but I think the question you alluded to, "should this happen with every conceivable create/save/etc.?" is a good general guideline. One thing to keep in mind when moving logic out of callbacks is that you'll no longer get the im…
Re: Rails, callbacks, workers, and the race you never expected to lose
#15Earlier quoted context omitted.
Absolutely agreed - better to make these things explicit somewhere rather than having your business logic implicitly handled by something directly coupled to your persistence layer (with the exception of data integrity tasks as mentioned by danenania). As a sort of half-way house between using lifecycle callbacks and sticking everything in the controller, I've just moved the main app I work on to a pub-sub event syst…
I would love to read a write up on how you accomplished this.
In the meantime, the pub/sub setup we've got is pretty similar to the one presented a little way down the following article:
https://www.theagileplanner.com/blog/building-agile-planner/...
Our listeners sit completely separate from the controllers, though, and we're not using them for anything like handling controller response logic (I'm not sure how I feel about that, although the idea is certainly interesting).
Re: Rails, callbacks, workers, and the race you never expected to lose
#16Emails are like async views. The model should not be responsible for rendering views. That's the responsibility of the controller. Which is why Action Mailer itself is modelled on Action Controller, uses Action View, and so forth.
He's not using the model to render the view, though, he's using it to queue up a future asynchronous request to the relevant mail "controller".
In traditional Rails design, the controller is exactly the right place for this. Another option is a service layer of some kind, if you do that, e.g. a DCI context, or just another Plain-Ol-Ruby-Object that is in charge of the logic of signing up a user.
The best part of separating out the logical business sequence of signing up a user into its own object (I can see this method in my head, something like save_new_user, sign_in_user, queue_welcome_email) is that it becomes massively easier to test - you can just mock the various calls to its collaborators' public methods because they should all have unit tests.
Re: Rails, callbacks, workers, and the race you never expected to lose
#17Note that even in the proposed solution, after_commit hooks offer no guarantee that the job will ever be enqueued, if for example redis is unavailable, or your process gets reaped between when the database commit and when the after_commit hook gets fired -- the commit has already happened. So if it's really important that your asynchronous task be queued, keeping the queue in your DB has some advantages.
Re: Rails, callbacks, workers, and the race you never expected to lose
#18Re: Rails, callbacks, workers, and the race you never expected to lose
#19Re: Rails, callbacks, workers, and the race you never expected to lose
#20Emails are like async views. The model should not be responsible for rendering views. That's the responsibility of the controller. Which is why Action Mailer itself is modelled on Action Controller, uses Action View, and so forth.