There's ways to do cleaner SRP that allow moving email delivery out of a model and controller and still be flexible for emailing different things based on type of user, etc.; it's merely a matter of how you solve the problem. simple.rb is the simplest thing that'll do basically the same exact thing that the original author intended - separate object, fast to test, blah blah blah. Introducing DI to override delivery is super simple and can be a lambda/Proc or method; WithDeliveryEmail
doesn't give a shit, as long as it has a call
method accepting the user to deliver the email to.
Is the solution of moving email delivery outside the callback of the user sensible? Can other developers figure out what the side effects of saving a user from the controller immediately? Does creating a user always ensure that an email is delivered? If the system does what it needs to do and all those can be answered with yes, I think it's a reasonable solution.
There's a thousand ways to skin this cat. I don't find any proposed implementation interesting, honestly. Primarily because this problem is far too contrived.
Regarding this particular implementation, I'm not a huge fan though I find some things I like.
What I like:
What I don't like:
The cognitive overhead involved with understanding your intentions here is beyond that of the original proposal. To read this code, I have to perform the following conscious steps (hope you don't mind honest thoughts):
While even the original blog code was over-engineered for this contrived example, you've added another layer of abstraction, Procs, and you end up managing them all over the place.
What I dislike about passing around Procs is the mix of OO and functional paradigms. Functional works great in JS but feels second class in Ruby. OOP is much better suited for Ruby than it is in JS. I like to leverage the powerful aspects of the particular language I'm using and I tend not to mix and match unless absolutely necessary. I don't feel this contrived example warrants the cognitive overhead of mixing paradigms.
Aside
You'll likely use user.save! instead and catch the exception in the controller to display/redirect the correct content. Which is why I have gripes with the original authors claim that we can be avoiding Java's "wrong way":
My Preference
FWIW, for this contrived example, I would much prefer to read this in a controller: