Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/javierav/haku
A library for build simple service objects
https://github.com/javierav/haku
actions poro rails ruby service-object
Last synced: about 2 months ago
JSON representation
A library for build simple service objects
- Host: GitHub
- URL: https://github.com/javierav/haku
- Owner: javierav
- License: mit
- Created: 2022-04-05T15:27:04.000Z (over 2 years ago)
- Default Branch: development
- Last Pushed: 2023-10-06T07:12:35.000Z (about 1 year ago)
- Last Synced: 2024-10-13T13:38:53.595Z (2 months ago)
- Topics: actions, poro, rails, ruby, service-object
- Language: Ruby
- Homepage:
- Size: 91.8 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Haku
![CI](https://github.com/javierav/haku/workflows/CI/badge.svg)
A simple library for build simple service objects.
## Status
> :warning: **This project is still experimental, use with caution!**
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'haku'
```And then execute:
```shell
bundle install
```## Usage
**Haku** is made up of four modules that add functionality to our service objects:
* [Haku::Core](#hakucore)
* [Haku::Delayable](#hakudelayable)
* [Haku::Eventable](#hakueventable)
* [Haku::Resourceable](#hakuresourceable)Additionally, it's available the [Haku::Controller](#hakucontroller) module for use in ours Rails controllers.
### Haku::Core
```ruby
class Users::Update
include Haku::Coreinput :user, :attributes
on_success :send_emaildef call
if user.update(attributes)
success! resource: user
else
failure! resource: user, errors: user.errors
end
endprivate
def send_email
UserMailer.with(user: user).update.deliver_later
end
endresponse = Users::Update.call(user: User.first, attributes: { name: "Javier" })
response.success? # => true
response.result # => { resource: }
response.resource # =>
```As you can see, if the payload passed to `success!` or `failure!` is a hash, each key of the hash can be accessed
directly in response object.### Haku::Delayable
```ruby
class Users::ComputeHours
include Haku::Core
include Haku::Delayableinput :user
def call
# compute expensive data for user
end
endUsers::ComputeHours.delayed.call(user: User.first)
```Use `delayed.call` instead of `call` for execute service object in background using `ActiveJob` job.
#### Customize job
```ruby
Users::ComputeHours.delayed(job: OtherJob).call(user: User.first)
```#### Customize job options
```ruby
Users::ComputeHours.delayed(job: OtherJob, queue: :low, priority: 2).call(user: User.first)
```You can pass the same options allowed by ActiveJob
[set](https://api.rubyonrails.org/v7.0.4/classes/ActiveJob/Core/ClassMethods.html#method-i-set) method:#### Config options
```ruby
# config/initializers/haku.rbHaku.configure do |config|
config.job_queue = "low_priority"
end
```| Config | Description | Default value |
|:------------|:---------------------------------|:--------------|
| `job_queue` | String or Symbol with queue name | `default` |### Haku::Eventable
```ruby
class Users::Update
include Haku::Core
include Haku::Eventableinput :user, :attributes
event resource: :userdef call
success! resource: user
end
endUsers::Update.call(user: User.first, attributes: { name: "Javier" })
# => call Event.create(name: "user:update", resource: User.first)
```The `name` attribute are calculated using the custom proc from `event_name` config option. You can change it with
```ruby
event name: "custom:name", resource: :user
```#### Properties passed to event model
For each property passed as payload of `event` class method, it will try to:
1. If is a block, it is called to get the value of property.
2. If is a symbol, a method is used to get the value of property:
3. In other case, uses the raw value.#### Config options
```ruby
# config/initializers/haku.rbHaku.configure do |config|
config.event_model = "EventLog"
end
```| Config | Description | Default value |
|:--------------------------|:------------------------------------------------------|:-------------------------------------------------------|
| `event_model` | Name of the model used for create events | `Event` |
| `event_property_for_name` | Property used for name in event model | `:name` |
| `event_name` | String or Proc to determine the event name | Custom Proc. Returns `user:create` for `Users::Create` |### Haku::Resourceable
This module include helpers to works with *ActiveRecord* compatible model resources, invoking `success!` or `failure!`
based in the result of the performed operation.```ruby
class Users::Update
include Haku::Core
include Haku::Resourceableinput :user, :attributes
on_success :send_emaildef call
update_resource(user, attributes)
endprivate
def send_email
UserMailer.with(user: user).update.deliver_later
end
end
```#### create_resource
Call to `create` or `_create` method of the `parent` object passing the `attributes` and storing
the result object in the `ivar` instance variable. Invoke `success!` if the model is persisted or `failure!` in other
case.| parameter | type | description |
|--------------|----------|------------------------------------------------------------------|
| `parent` | `Object` | Parent object where new resource will be created |
| `attributes` | `Hash` | Attributes for create |
| `ivar` | `Symbol` | Name of the instance variable used to access to the new resource |
| `options` | `Hash` | Options hash |##### options
| parameter | type | description |
|-------------|----------|----------------------------------------------------------------------|
| `singleton` | `Symbol` | If the resource should be created using `_create` suffix. |#### update_resource
Call to `update` method of the `resource` object passing `attributes`to it. Invoke `success!` if the model is updated or
`failure!` in other case.| parameter | type | description |
|--------------|----------|------------------------|
| `resource` | `Object` | Resource to be updated |
| `attributes` | `Hash` | Attributes to update |#### destroy_resource
Call to `destroy` method of the `resource`. Invoke `success!` if the model is destroyed or `failure!` in other case.
| parameter | type | description |
|--------------|----------|--------------------------|
| `resource` | `Object` | Resource to be destroyed |#### persist_resource
| parameter | type | description |
|----------------|----------|---------------------------------------------|
| `resource` | `Object` | Resource to be destroyed |
| `save_options` | `Hash` | Options passed to `save` method of resource |For more info please view the [source code](lib/haku/resourceable.rb) of the module.
### Haku::Controller
```ruby
class UsersController < ApplicationController
include Haku::Controllerbefore_action :find_user
def update
execute Users::Update, user: @user, attributes: update_paramsif execution.success?
redirect_to user_path(execution.resource)
else
render :edit, errors: execution.errors
end
endprivate
def find_user
@user = User.find(params[:id])
enddef update_params
params.require(:user).permit(:first_name, :last_name)
end
end
```### Using parent class
```ruby
class ApplicationAction
include Haku::Core
include Haku::Resourceable
include Haku::Eventable
endclass Users::Update < ApplicationAction
end
```## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
You can also run `bin/console` for an interactive prompt that will allow you to experiment.To install this gem onto your local machine, run `bundle exec rake install`.
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to
[rubygems.org](https://rubygems.org).## Contributing
Bug reports and pull requests are welcome, please follow
[Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow).## Code of Conduct
Everyone interacting in the Haku project's codebases, issue trackers, chat rooms and mailing lists is expected to
follow the [code of conduct](https://github.com/javierav/haku/blob/development/CODE_OF_CONDUCT.md).## License
Copyright © 2022-2023 Javier Aranda. Released under the terms of the [MIT license](LICENSE).