以下是服务的外观:
class UpdateCompositionAuthorsService
attr_accessor *%w(
args
).freeze
class << self
def call(args={})
new(args).call
end
end # Class Methods
#======================================================================================
# Instance Methods
#======================================================================================
def initialize(args={})
@args = args
assign_args
end
def call
do_stuff_to_update_authors
generate_the_pdf
end
private
def do_stuff_to_update_authors
# do your 'batch' stuff here
end
def generate_the_pdf
# do your one-time logic here
end
def assign_args
args.each do |k,v|
class_eval do
attr_accessor k
end
send("#{k}=",v)
end
end
end
你可以这样称呼它:
UpdateCompositionAuthorsService.call(composition: @composition, authors: @authors)
我厌倦了记住要发送给我的服务类的参数,所以我创建了一个名为ActsAs::CallingServices
. 当包含在一个class
想要调用服务的模块中时,该模块提供了一个调用的方法call_service
,让我可以执行以下操作:
class FooClass
include ActsAs::CallingServices
def bar
call_service UpdateCompositionAuthorsService
end
end
然后,在服务类中,我包含一些额外的类级数据,如下所示:
class UpdateCompositionAuthorsService
SERVICE_DETAILS = [
:composition,
:authors
].freeze
...
def call
do_stuff_to_update_authors
generate_the_pdf
end
...
end
调用类(FooClass
在本例中为 )用于UpdateCompositionAuthorsService::SERVICE_DETAILS
构建适当的参数散列(省略详细信息)。
我的服务类中还有一个名为good_to_go?
(省略详细信息)的方法,因此我的调用方法通常如下所示:
class UpdateCompositionAuthorsService
...
def call
raise unless good_to_go?
do_stuff_to_update_authors
generate_the_pdf
end
...
end
因此,如果参数集不好,我会立即知道,而不是nil
在我的服务中间的某个地方遇到错误。