Recently I was building a complex logic controller and wanted to refactor it due to “Single responsibility” principle. So I read about Services. But sometimes later I saw concerns. I though that it’s a replacement for Services in ruby (since there is no default Services folder and etc.), but couldn’t find any good article like “concerns vs services” or etc.
Than I heard that concerns is for model and services for controller, but still, can’t find any topic or article that are proving this.
Can anybody explain the difference of services and concerns and when to use them?
Concerns and services are very different abstraction patterns used for entirely different purposes.
Say I want to authenticate a user. I could easily just write a authenticate(username, password)
function, but it might be useful to encapsulate the logic for that function in a class instead:
class AuthenticationService
def initialize(username, password); end
def run(); end
end
Aside from helping me encapsulate all of the logic for authentication in a single class, this allows me to create other authentication classes.
class GoogleAuthenticationService
def initialize(username, password); end
def run(); end
end
class FacebookAuthenticationService
def initialize(username, password); end
def run(); end
end
A concern, on the other hand, mixes functionality from a module into another class. Say you have a Rails controller that was concerned with authorizing a user. You might write a concern that implements a before_action
which checks to see if the user is authorized. Then you could mix that concern into any controller where you wanted to enforce that authorization check.
Concerns are essentially modules that allow you to encapsulate aspects of models into separate files to DRY up your code. The advantage is that they inherit from the ActiveSupport:Concern module, so you can access the ActiveRecord operations like validations and associations for the model in which the concern is included.
Service objects are used primarily to wrap a method in an object. These are useful in splitting logic up into small reusable components. These are often used for decoupling systems, and making systems easier to understand, because fundamentally what they do take you from a few many-purpose classes to many classes with a single purpose.
I have my concerns about concerns and tend to err on the side of caution with them.
Fny's answer has just shown up for me whilst writing and I think should be the accepted answer :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With