ActionService v2.x
Welcome to Action Service gem, is a ruby gem to create and interact easily with services.
Why services
This is where you can add your code to perform a simple function instead of making complex controllers or models.
Installation
Add this line to your application's Gemfile:
gem 'action_service'
And then execute:
$ bundle
Or install it yourself as:
$ gem install action_service
Setting up
To start to use the gem execute:
$ rails g service:application_service
This command will generate application service (is the parent class for all your services), application service is inheriting from the action service base class, and you can overwrite all methods.
Usage
You can start to use action service by generating service to execute a specific logic, Example: Run next command to generate service for authenticating an admin
$ rails g service Admin::Authenticate
this will add a new directory for admin inside app/services if not exist, and generate authenticate_service.rb
Running via Spring preloader in process 30051
create app/services/admin/authenticate_service.rb
And when you open authenticate_service.rb will be like this
class Admin::AuthenticateService < ApplicationService
def initialize()
super()
end
def call
self
end
end
ApplicationService class
All generated services are inheriting from ApplcaitonService, ApplicationService is inherited from `ActoinService::Base, So all service will contain:
Three instance variables
@successis a boolean withtrueas the default value, and if you add any error this flag will be changed tofalse.@errorsis an array containing a list of errors.@responseis a hash to add service response (values, objects, etc.). #### Six instance methodssuccess?to get boolean if service is executed successfully or not (based on adding errors).errorsto get a list of errors.responseto get the response hash.add_error(error_message)to add error (will change@successtofalse), Exampleadd_error("wrong admin id").add_errors(*error_messages)to add errors as parameters or array (will change@successtofalse), Exampleadd_errors("email is required","phone number is aready exist")ORadd_errors(["email is required","phone number is aready exist"]).
Now, let's implement Admin::AuthenticateService
class Admin::AuthenticateService < ApplicationService
def initialize(email, password)
super()
@admin = Admin.find_by(email: email)
@password = password
end
def call
add_error "wrong admin email" and return self if not @admin
add_error "wrong password" and return self if not @admin.authenticate(@password)
@response[:admin] = @admin
self
end
end
This service is now ready to be used, For example, we will call the service inside a controller
result = Admin::AuthenticateService.new(params[:email], params[:password]).call
if result.success?
# {success: true, response: {admin object}, errors: []}
render json: { success: result.success?, response: result.response, errors: result.errors }
else
# {success: false, response: {}, errors: ["wrong email" OR "wrong password"]}
render json: { success: result.success?, response: result.response, errors: result.errors }, status: :unauthorized
end
Services layer will help you to write clean code, by small models, controller and DRY code (don't repeat yourself), you can use service inside another service and stop executing the first service if the second one fails, Example:
class Cache::List::AddHashService < ApplicationService
def initialize(list_key, hash_key, hash_data, expiry_datetime=nil)
super()
@list_key = list_key
@hash_key = hash_key
@hash = hash_data
@expiry_datetime = expiry_datetime
end
def call
result = Cache::Hash::SetService.new(hash_key, hash_data, @expiry_datetime).call
# if Cache::Hash::SetService fails will stop excuting and return the errors
add_errors result.errors and return self if not result.success?
result = Cache::List::AddService.new(list_key, hash_key, @expiry_datetime).call
# if Cache::List::AddService fails will stop excuting and return the errors
add_errors result.errors and return self if not result.success?
self
end
end
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/abdofawzi5/action_service. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open-source under the terms of the MIT License.