Class: Utilisable::Service
- Inherits:
-
Object
- Object
- Utilisable::Service
- Defined in:
- lib/utilisable/service.rb
Overview
Interface for running services - a place to move your business logic. Example: class TestService < ApplicationUtilities::Service
attr_reader :user_id
def initialize(user_id)
@user_id = user_id
end
def call
return broadcast(:fail) unless user_valid?
do_some_stuff
book = user.books.last
user.delete
broadcast(:ok, book)
end
private
def user_valid?
user.name == 'Kyle'
end
def do_some_stuff
#..more_code_here..
end
def user
@user ||= User.find_by(id: user_id)
end
end
TestService.call(@user.id) # will delete user and won't affect 'broadcast' method
TestService.call(@user.id) do |obj|
obj.on(:fail) { raise 'Some error' }
obj.on(:ok) { |book| @book = book }
end
@user.update(name: 'Stan') TestService.call(@user.id) do |obj|
obj.on(:fail) { raise 'Some error' }
obj.on(:ok) { |book| @book = book }
end # 'Some error' will be raised
Some code here is commented - it is needed in order not to write 'obj.on' for setting listeners, and writing only 'on'. But this approach encapsulates listener blocks from controllers where they being called. It may be a good thing, but I found it irritating. Current approach allows us to return objects from service via broadcasts, which might be helpful.
Direct Known Subclasses
Class Method Summary collapse
Instance Method Summary collapse
- #broadcast(name, *args) ⇒ Object
- #call ⇒ Object
-
#initialize(*args) ⇒ Service
constructor
A new instance of Service.
-
#local_registrations ⇒ Object
def call_registrations local_registrations.select { |registration| !registration.arguments.nil? }.each(&:broadcast) end.
- #on(name, &block) ⇒ Object
- #transaction(&block) ⇒ Object
Constructor Details
#initialize(*args) ⇒ Service
Returns a new instance of Service.
70 |
# File 'lib/utilisable/service.rb', line 70 def initialize(*args); end |
Class Method Details
.call(*args) {|obj| ... } ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/utilisable/service.rb', line 60 def self.call(*args) obj = new(*args) # obj.evaluate(&block) if block_given? yield obj if block_given? obj.call # obj.call_registrations # nil end |
Instance Method Details
#broadcast(name, *args) ⇒ Object
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/utilisable/service.rb', line 72 def broadcast(name, *args) # TODO: add global listeners local_registrations.select { |registration| registration.name == name }.first&.broadcast(*args) self # registration = local_registrations.find { |registration| registration.name == name } # return if registration.nil? # # registration.arguments = *args # self end |
#call ⇒ Object
105 106 107 |
# File 'lib/utilisable/service.rb', line 105 def call raise NoMethodError end |
#local_registrations ⇒ Object
def call_registrations
local_registrations.select { |registration| !registration.arguments.nil? }.each(&:broadcast)
end
def evaluate(&block)
@caller = eval('self', block.binding, __FILE__, __LINE__)
instance_eval(&block)
end
101 102 103 |
# File 'lib/utilisable/service.rb', line 101 def local_registrations @local_registrations ||= Set.new end |
#on(name, &block) ⇒ Object
87 88 89 90 |
# File 'lib/utilisable/service.rb', line 87 def on(name, &block) local_registrations << BlockRegistration.new(name, block) self end |
#transaction(&block) ⇒ Object
83 84 85 |
# File 'lib/utilisable/service.rb', line 83 def transaction(&block) ActiveRecord::Base.transaction(&block) if block_given? end |