Created
August 10, 2021 07:34
-
-
Save fuksito/c4469a163f9ebe2868094aa6262fa306 to your computer and use it in GitHub Desktop.
CallableService Concern for Rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Usually service classes have only one purpose and thus should have only one public method that triggers action | |
# This module simplifies the common approach: | |
# | |
# SomeService.new(a, b, c).call | |
# | |
# To: | |
# | |
# SomeService.call(a, b, c) | |
# | |
# Requirements for class: | |
# | |
# 1. Have instance method #call | |
# 2. include CallableService | |
# | |
# Use cases: | |
# | |
# 1. Can be used instead of Sidekiq worker when worker just delegates to service | |
# SomeService.delay.call(a, b, c) | |
# | |
# 2. Less code in specs when checking expectation that service was called | |
# | |
# expect(SomeService).to receive(:call).with(a, b, c) | |
# | |
# instead of: | |
# | |
# service = double(SomeService) | |
# expect(service).to receive(:call) | |
# expect(SomeService).to receive(:new).with(a,b,c).and_return(service) | |
# | |
# 3. Can be used in maps | |
# | |
# ['Check Up', 'Covid-19 Testing'].map(&StringFormatService) | |
# | |
# instead of | |
# | |
# ['Check Up', 'Covid-19 Testing'].map do |string| | |
# StringFormatService.new(string).call | |
# end | |
# | |
# 4. Can still be initiated with #new to debug inner state, like | |
# | |
# service = SomeService.new(a,b,c) | |
# service.send(:some_private_method) | |
# | |
module CallableService | |
extend ActiveSupport::Concern | |
module ClassMethods | |
def call(*args, &block) | |
new(*args, &block).call | |
end | |
def to_proc | |
public_method(:call).to_proc | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment