Skip to content
master
Go to file
Code

Latest commit

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Code Climate Codeship Status for nebulab/simple_command

SimpleCommand

A simple, standardized way to build and use Service Objects (aka Commands) in Ruby

Requirements

  • Ruby 2.0+

Installation

Add this line to your application's Gemfile:

gem 'simple_command'

And then execute:

$ bundle

Or install it yourself as:

$ gem install simple_command

Usage

Here's a basic example of a command that authenticates a user

# define a command class
class AuthenticateUser
  # put SimpleCommand before the class' ancestors chain
  prepend SimpleCommand
  include ActiveModel::Validations

  # optional, initialize the command with some arguments
  def initialize(email, password)
    @email = email
    @password = password
  end

  # mandatory: define a #call method. its return value will be available
  #            through #result
  def call
    if user = User.find_by(email: @email)&.authenticate(@password)
      return user
    else
      errors.add(:base, :failure)
    end
    nil
  end
end

in your locale file

# config/locales/en.yml
en:
  activemodel:
    errors:
      models:
        authenticate_user:
          failure: Wrong email or password

Then, in your controller:

class SessionsController < ApplicationController
  def create
    # initialize and execute the command
    # NOTE: `.call` is a shortcut for `.new(args).call`
    command = AuthenticateUser.call(session_params[:email], session_params[:password])

    # check command outcome
    if command.success?
      # command#result will contain the user instance, if found
      session[:user_token] = command.result.secret_token
      redirect_to root_path
    else
      flash.now[:alert] = t(command.errors.full_messages.to_sentence)
      render :new
    end
  end

  private

  def session_params
    params.require(:session).permit(:email, :password)
  end
end

Test with Rspec

Make the spec file spec/commands/authenticate_user_spec.rb like:

describe AuthenticateUser do
  subject(:context) { described_class.call(username, password) }

  describe '.call' do
    context 'when the context is successful' do
      let(:username) { 'correct_user' }
      let(:password) { 'correct_password' }
      
      it 'succeeds' do
        expect(context).to be_success
      end
    end

    context 'when the context is not successful' do
      let(:username) { 'wrong_user' }
      let(:password) { 'wrong_password' }

      it 'fails' do
        expect(context).to be_failure
      end
    end
  end
end

Contributing

  1. Fork it ( https://github.com/nebulab/simple_command/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A simple, standardized way to build and use Service Objects (aka Commands) in Ruby

Topics

Resources

License

Packages

No packages published

Languages

You can’t perform that action at this time.