Here's another version that doesn't even use private methods in the controller and uses a PORO for the email grouping: https://gist.github.com/dhh/9333991
I think a lot of blog posts use trivial and contrived examples for the point of explaining the concept. There's not a lot of people out there that are good at explaining complicated refactorings. Katrina Owen comes to mind as one of the few that is good at explaining such refactorings.
Perhaps if someone made a post like this with starting code that was more complex it would be a better example, and also harder for you to counter it with a couple gists ;)
Thanks for writing this. While I often look for ways to take external-interaction-responsibility away from Rails objects, the OP didn't really make sense to me, at least in terms of saving time and making things more logical.
However, there's a distinction that has to be made in your example and the OP's. In the OP, the failure of the Interactor, including the delivery of emails, would cause the controller to enter the "failure" branch:
if interactor.success?
redirect_to home_path
else
flash[:error] = interactor.message
render :new
end
Whereas your example, the controller would take the successful branch if the data model was saved, regardless of whether email delivery failed:
if @grouper.save
ConfirmedGrouperEmails.new(@grouper).deliver
AssignBarForGrouper.enqueue(@grouper.id)
redirect_to home_path
else
render :new
end
So we're not comparing apples to apples here. However, as a layperson, I'd have to agree with you: Why should the error be raised to the grouper-creating user, when it should be going to the part of the system that handles mailing? But maybe the actual details are more complicated than that...
Why would the delivery of the emails fail? Because your SMTP server is down? That's an exceptional state, handle it with exceptions -- not with conditions.
Or maybe because the email addresses are invalid? Handle that when they are captured. It's way too late for that here.
rubiquity|12 years ago
Perhaps if someone made a post like this with starting code that was more complex it would be a better example, and also harder for you to counter it with a couple gists ;)
jlangenauer|12 years ago
To my mind, this code is much clearer, which proves the OPs point.
danso|12 years ago
However, there's a distinction that has to be made in your example and the OP's. In the OP, the failure of the Interactor, including the delivery of emails, would cause the controller to enter the "failure" branch:
Whereas your example, the controller would take the successful branch if the data model was saved, regardless of whether email delivery failed: So we're not comparing apples to apples here. However, as a layperson, I'd have to agree with you: Why should the error be raised to the grouper-creating user, when it should be going to the part of the system that handles mailing? But maybe the actual details are more complicated than that...dhh|12 years ago
Or maybe because the email addresses are invalid? Handle that when they are captured. It's way too late for that here.
Axsuul|12 years ago
iamwil|12 years ago
cheshire137|12 years ago
dragonwriter|12 years ago
unknown|12 years ago
[deleted]
the_fury|12 years ago
unknown|12 years ago
[deleted]