Live data from Hacker News

Rails – The Missing Parts

eng.joingrouper.com

71–80 of 173 posts

Re: Rails – The Missing Parts

#71
post #54

Earlier quoted context omitted.

Yes, rewriting a system after it's already settled and designed can indeed bring a cleaner code base about. But don't confuse that with "better architecture". Don't even get me started on the hand-wavy "loosely coupled". If this is a poor example, pick a good example. I'll be happy to code ping pong you whatever example you choose. One way to spend hundreds of thousands of LOC on an application is to stuff it with ne…

I hope I am not sticking my head into the lion's mouth here, but here ( https://gist.github.com/BiggerNoise/9334673 ) is a link to a gist of some code in one of our apps. Cases have Tasks and Activities. Activities are always associated with a case, and may be associated with a task. In the controller, when assigning a case, one would type: AssignCaseCommand.new(params).execute! The command class implements the Comma…

If reassigning a case is part of the domain, it belongs in the model.

I don't know how to put this gently, but this concoction looks like a hot mess with no separation between modeling and controlling.

These commands have a ton of domain logic all tangled up with activity reporting, formatting, and parameter parsing. It looks like a big ball of mud to me :(

Re: Rails – The Missing Parts

#72
post #56
post #52

Earlier quoted context omitted.

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

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…

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.

Re: Rails – The Missing Parts

#73
post #54

Earlier quoted context omitted.

Yes, rewriting a system after it's already settled and designed can indeed bring a cleaner code base about. But don't confuse that with "better architecture". Don't even get me started on the hand-wavy "loosely coupled". If this is a poor example, pick a good example. I'll be happy to code ping pong you whatever example you choose. One way to spend hundreds of thousands of LOC on an application is to stuff it with ne…

You can't possibly think that there's never a use case for the Interactor pattern. Please watch Uncle Bob's talk: http://www.confreaks.com/videos/759-rubymidwest2011-keynote-...

Let's just say I have philosophical differences with the views presented in that presentation.

Also, I never said never. I said this particular example was a poor example and the general principle derived from it was equally poor. Garbage in, garbage out.

Re: Rails – The Missing Parts

#74
post #48

Earlier quoted context omitted.

Coulda, woulda, damn shoulda. You're future coding with your "what ifs". Most controller actions are not reused. The time to extract for reuse is when you need to reuse. Not crystal balling about that you probably will be in the future. Because when the reuse case actually arrives, you might find that you need to reuse some, but not all of the action. If you're literally doing the exact same thing for both web and ap…

Sure, I think we're saying the same thing here. This example is from a real-life codebase, and the interactor was extracted from 3 or 4 (bloated, repetitive) controllers. Perhaps this could have been made clearer in the post. I'm not arguing at all that every controller needs an Interactor, or all Rails codebases should start out with Interactors present. I am saying that Interactors are very useful concepts for re-u…

Please do share the 3 or 4 controllers all sharing this logic. I'd be happy to play code pong with them.

Re: Rails – The Missing Parts

#75
post #70

Earlier quoted context omitted.

My contention is that there often are times when the complexity of the business requires a fairly extensive set of operations to occur in concert, including the creation of several models, email-sending etc. In this case, the Right Place (tm) to put these is in POROs / Interactors that can be tested in isolation and re-used across the code-base if necessary. This code should not live in controllers and certainly not…

> In this case, the Right Place (tm) to put these is in POROs / Interactors that can be tested in isolation and re-used across the code-base if necessary. Key phrase: "if necessary". It sounds like you're advocating for building abstractions before you actually have a reason to use them. Your reason seems to be "we may need to reuse them in the future" or, "one can see where we might move in a direction where we'd wa…

> It sounds like you're advocating for building abstractions before you actually have a reason to use them.

If it sounds that way, I've over-simplified the examples in the blog post in the interests of clarity. I'll take more care in future! The specific interactor in question is used in 4 separate places.

From the post:

> You obviously need to choose the patterns that fit the problem you’re trying to solve – it’s rarely one-size-fits-all, and some of these principles may be overkill in a very simple 15-minute blog application.

Re: Rails – The Missing Parts

#76
post #54

Earlier quoted context omitted.

I've spent the last few months re-writing a medium-sized code-base (several hundred thousand LoC) that looks like your version into code that looks like the blog version. Test suite run time has dramatically decreased, code is more loosely coupled and we see far fewer bugs. > You obviously need to choose the patterns that fit the problem you’re trying to solve – it’s rarely one-size-fits-all, and some of these princi…

Yes, rewriting a system after it's already settled and designed can indeed bring a cleaner code base about. But don't confuse that with "better architecture". Don't even get me started on the hand-wavy "loosely coupled". If this is a poor example, pick a good example. I'll be happy to code ping pong you whatever example you choose. One way to spend hundreds of thousands of LOC on an application is to stuff it with ne…

> POROs are great, though. Our app/models is full of them. We even added app/services too. The trouble I have is with people who, like you, fall in love with the flawed notion that their application is such a special snowflake that it deserves "advanced techniques".

The main difference I see between the Rails philosophy and most of these "Use SRP and Interactors and things!" blog posts are that Rails is way more interested in using the correct tool for the job, and most of these blog posts are of the "use this for everything and every one!" variety.

I have one project right now that I decided I wanted a Command for one action. I'm accepting input from a webhook that I can perform asynchronously, it interacts with like 5 different models, and I wanted to beat up on the tests pretty thoroughly. So I did that.

Elsewhere I'm using concerns to make like 4 different models easily sortable.

And other places I'm using Module#concerning to keep models organized.

ONE TRUE WAY is overrated. I'd rather use whatever works given the context.

Re: Rails – The Missing Parts

#77
post #71

Earlier quoted context omitted.

I hope I am not sticking my head into the lion's mouth here, but here ( https://gist.github.com/BiggerNoise/9334673 ) is a link to a gist of some code in one of our apps. Cases have Tasks and Activities. Activities are always associated with a case, and may be associated with a task. In the controller, when assigning a case, one would type: AssignCaseCommand.new(params).execute! The command class implements the Comma…

If reassigning a case is part of the domain, it belongs in the model. I don't know how to put this gently, but this concoction looks like a hot mess with no separation between modeling and controlling. These commands have a ton of domain logic all tangled up with activity reporting, formatting, and parameter parsing. It looks like a big ball of mud to me :(

> It looks like a big ball of mud to me :(

That is of course the most popular of all architectural patterns. :)

Re: Rails – The Missing Parts

#78
post #71

Earlier quoted context omitted.

I hope I am not sticking my head into the lion's mouth here, but here ( https://gist.github.com/BiggerNoise/9334673 ) is a link to a gist of some code in one of our apps. Cases have Tasks and Activities. Activities are always associated with a case, and may be associated with a task. In the controller, when assigning a case, one would type: AssignCaseCommand.new(params).execute! The command class implements the Comma…

If reassigning a case is part of the domain, it belongs in the model. I don't know how to put this gently, but this concoction looks like a hot mess with no separation between modeling and controlling. These commands have a ton of domain logic all tangled up with activity reporting, formatting, and parameter parsing. It looks like a big ball of mud to me :(

Perhaps that's why the OP used a simple example. Complex examples are pretty hard to get your head around at first glance; even sane systems can be perceived as a 'hot mess' upon a quick read without any context.

I disagree that re-assigning a case belongs in the case model. It is a complex interaction between several models. Extracting it to a command object allows all of the rules to be easily understood.

Re: Rails – The Missing Parts

#79
post #52
post #47

Earlier quoted context omitted.

I rewrote the code in this example to use the "Beginner's Version" of Rails ( sigh ). You judge which you like better: https://gist.github.com/dhh/9333694

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 can't seem to find it on Google. What's a PORO?

Re: Rails – The Missing Parts

#80
post #79
post #52

Earlier quoted context omitted.

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 can't seem to find it on Google. What's a PORO?

Plain Old Ruby Object, as opposed to an ActiveRecord model.
Post reply on HN