Redress
¶ ↑
Motivation (Command pattern)¶ ↑
The command pattern is sometimes called a service object, an operation, an action, and probably more names that I’m not aware of. Whatever the name we gave it, the purpose of such a pattern is rather simple: take a business action and put it behind an object with a simple interface.
Table of Contents¶ ↑
Requirements¶ ↑
-
wisper
-
dry-struct
-
hashie
Optional¶ ↑
To support validations just add activemodel to your project
-
activemodel
Setup¶ ↑
For an insecure install, type the following:
gem install redress
Add the following to your Gemfile:
gem "redress"
Usage¶ ↑
Forms¶ ↑
# app/forms/application_form.rb require 'redress/form' class ApplicationForm < Redress::Form end
Let’s define simple form (Built-in Types dry-rb.org/gems/dry-types/built-in-types/):
class SimpleForm < ApplicationForm mimic :user define_schema do attribute :nickname, Redress::Types::Strict::String.default('superman') attribute :name, Redress::Types::StrippedString attribute :email, Redress::Types::StrippedString attribute :name_with_email, String attribute :age, Redress::Types::Coercible::Integer attribute :terms_of_service, Redress::Types::Bool end validates :name, presence: true validates :email, presence: true def map_model(user) self.name_with_email = "#{user.name} <#{user.email}>" end end
Form with default values (dry-rb.org/gems/dry-types/default-values/):
require 'securerandom' class CommentForm < Redress::Form define_schema do attribute(:id, Redress::Types::Coercible::String.default { SecureRandom.uuid }) attribute(:content, Redress::Types::String) end validates :content, presence: true end
Form with multiple comments:
class CommentForm < Redress::Form define_schema do attribute :id, Redress::Types::Coercible::Integer attribute :content, Redress::Types::String end validates :content, presence: true end class OrderForm < Redress::Form mimic :order define_schema do attribute :title, Redress::Types::String attribute :comments, Redress::Types::Array.of(CommentForm) end end
Form with context:
class CommentForm < Redress::Form define_schema do attribute :id, Redress::Types::Coercible::Integer attribute :content, Redress::Types::String end validates :content, presence: true validate :unsure_order_state_waiting private def unsure_order_state_waiting context.order.state?(:waiting) end end CommentForm.new(content: 'Hi').with_context(order: order)
Commands¶ ↑
# app/commands/application_command.rb require 'redress/command' class ApplicationCommand < Redress::Command end
Simple command for user registration:
# app/commands/users/create_command.rb module Users class CreateCommand < ApplicationCommand def initialize(form) @form = form end def call return Failure(@form) if @form.invalid? user = User.new(@form.attributes) if user.save Success(user) else Failure(user) end end end end
Controllers¶ ↑
# app/controllers/users_controller.rb class UsersController < Account::BaseController respond_to :json, only: :update def new @user_form = SimpleForm.new end def create @user_form = SimpleForm.from_params(params) Users::CreateCommand.call(@user_form) do |c| c.success { head status: 201 } c.failure { |form| render status: 422, json: { errors: form.errors } } end end end
Tests¶ ↑
To test, run:
bundle exec rspec ./spec/
Versioning¶ ↑
Read Semantic Versioning for details. Briefly, it means:
-
Major (X.y.z) - Incremented for any backwards incompatible public API changes.
-
Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.
-
Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.
Code of Conduct¶ ↑
Please note that this project is released with a CODE OF CONDUCT. By participating in this project you agree to abide by its terms.
Contributions¶ ↑
Read CONTRIBUTING for details.
License¶ ↑
Copyright © 2017 Fodojo LLC. Read LICENSE for details.
History¶ ↑
Read CHANGES for details. Built with Gemsmith.
Credits¶ ↑
Developed by Igor Galeta at Fodojo LLC.