New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor business logic to a service layer #433
Comments
|
Have you seen u-case? |
I haven't, no! I'm trying to stay as "boring" as possible right now but I will take a look for inspiration. Do you use it in your projects? |
Yes. I started "boring" as well. Once a controller starts to be more complex than simple operations I eventually extract to a domain layer with usecases. |
|
That's pretty slick, and I could see it working really well in super-large applications. That said, I wonder if it becomes a bit of an over-abstractions when you're just dealing with 5-10 people contributing at any given time. |
|
This project
I'm new to rails. Didn't build a lot of projects but I think it brings convention and good design to bigger teams. |
|
For the 'create developer' task I know that a CreateDeveloper usecase would exist somewhere. |
|
You could consider interactor It's nice to use very lightweight interactors that call helper modules or classes which in turn are super easy to test in isolation. |
|
No, business logic is not scattered all across your app. The business logic should be in only one place: the models. I've read Dave's Sustainable Rails book and I fully understand where he's coming from because I have worked at projects where everything is a mess (from actual SQL queries in the view to multiple layers of abstraction for doing simple things like listing the user's details) and every single time extracting "service objects" worked great. But I think that it worked great because:
However, I don't think it's a very good idea to start with a service layer because Rails already provides a place where you should place all your domain logic and that is the I think that a lot of developers forgot that code should be continuously refactored and we end up looking at a large piece of code and decide that we need to extract "service objects" or something similar. I was surprised when I read Jimmy Bogard's series of articles called "Domain-Driven Refactoring" and realized that refactoring, for me, gradually became this huge undertaking that involved changing a lot of code at once instead of refining it in small pieces (there are a lot of reasons for doing that, pressure from product managers to push a fix as soon as possible being one of them). What's very interesting to me is that I've enjoyed your approach of keeping the app as vanilla Rails as possible. There's a lot you can you within that Anyway, looking forward to see how the project evolves :-) |
Thanks @andreimaxim, I needed to hear this. The more service layer/objects I write the worse I feel about them. All I want to do is extract a DSL or parent object when I really want freedom to return whatever makes the most sense. I also feel like I'm adding more and more code, and more and more indirection, to not accomplish much. Testing controllers via integration tests isn't hard these days. Yes, they are much slower than a unit level test. But I feel like with a sub 10 second test suite that's a trade off I'm willing to make. I'm going to close this issue and accompanying PR #434 for now. Thanks to everyone who provided feedback! |


I attended a talk at RailsConf that really got me thinking. Your Service Layer Needn't be Fancy, It Just Needs to Exist from David Copeland, author of Sustainable Web Development with Ruby on Rails.
The gist was that all of your business logic is scattered across your app. If you need to know what your app does you have to open models, controllers, jobs, and maybe even some views. Instead, he proposed moving all business-specific code to a service layer.
Note "layer" and not object. He doesn't care how you do it (POROs were recommended) just that it has to exist. And it doesn't need to be complicated.
Based on that I'm inspired to try and consolidate some business logic of railsdevs into
services/. I kind of already started this with #387 but it could be extended further. Here are some high-level guidelines for what I'm planning.services/CreateDeveloper#create_developer(developer_params)is better thanDeveloperService.create(params)- explicit about exactly what each class and method doesThe text was updated successfully, but these errors were encountered: