Last active
December 3, 2019 13:42
-
-
Save IlyaDonskikh/3e20a5f43d932d5c7bb66e2af8f51764 to your computer and use it in GitHub Desktop.
Services Concept
This file contains 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
# frozen_string_literal: true | |
class ApplicationService | |
attr_reader :errors | |
## Etc. | |
def self.call(params) | |
new(params).process | |
end | |
def initialize(params = {}) # partent service method | |
params.each do |attr, value| | |
self.public_send("#{attr}=", value) | |
end | |
@errors = ErrorService.new(self) | |
end | |
def process | |
self | |
end | |
def success? | |
errors.blank? | |
end | |
def failed? | |
!success | |
end | |
private | |
def valid? | |
validate! | |
success? | |
end | |
end |
This file contains 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
class ErrorService | |
attr_reader :caller_instance | |
def initialize(caller_instance) | |
@caller_instance = caller_instance | |
end | |
def errors | |
@errors ||= {} | |
end | |
def messages(flat: false) | |
messages = {} | |
errors.each do |key, value| | |
key_localized = localize(".keys.#{key}") | |
messages[key] = | |
value.map do |message| | |
message_localized = localize(".values.#{key}.#{message}") | |
"#{key_localized} #{message_localized}" | |
end | |
end | |
flat ? flatten_messages(messages) : messages | |
end | |
def blank? | |
errors.empty? | |
end | |
def add(key, value) | |
# ToDo: Add only uniq | |
list = errors[key] | |
return errors[key] = [value] unless list | |
errors[key] = list.push(value) | |
end | |
private | |
def localize(name, attrs = {}) | |
hierarchy_path = caller_instance.class.to_s.underscore.gsub('/', '.') | |
I18n.t("services.#{hierarchy_path}.errors.#{name}", attrs) | |
end | |
def flatten_messages(messages) | |
messages.map { |_, value| value }.flatten | |
end | |
end |
This file contains 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
# frozen_string_literal: true | |
class MakeItSimple < ApplicationService | |
attr_accessor :company_id, :chain_id, :group_id, :step | |
## Consts | |
VALID_CHAIN_WORKFLOW_STATES = %w(initialized rejected) | |
## Etc. | |
def process | |
assing_items! if valid? | |
super | |
end | |
private | |
def assing_items! | |
emails = group.users_of_self_and_descendants.pluck(:email) | |
emails.each { |e| chain.approval_results.create(step: step, email: e) } | |
end | |
def group | |
@group ||= Group.of_company(company_id).find_by(id: group_id) | |
end | |
def chain | |
# Have to add company id to the chain table for security reasons | |
@chain ||= ApprovalResultChain.find_by(id: chain_id) | |
end | |
def validate! | |
errors.add(:company_id, :blank) unless company_id | |
errors.add(:group_id, :present) unless group | |
errors.add(:chain_id, :present) unless chain | |
errors.add(:chain_id, :invalid_state) unless chain_state_is_valid? | |
errors.add(:step, :invalid) unless step_valid? | |
end | |
def step_valid? | |
return true unless chain | |
chain.available_steps.include?(step.to_i) | |
end | |
def chain_state_is_valid? | |
return true unless chain | |
state = chain.find_state_machine(Workflow::APPROVAL_RESULT_WORKFLOW).state_id | |
VALID_CHAIN_WORKFLOW_STATES.include? state | |
end | |
end |
This file contains 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
service = MakeItSimple.call(company_id: compnay.id) | |
service.success? => # false | |
service.errors.messages => { chain_id: [Цепочка согласований не указана, ..], .. } | |
service.errors.messages(flat: true) => [Цепочка согласований не указана, .., ..] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment