Skip to content

Getting Started

Artem Shevchenko edited this page Nov 14, 2025 · 7 revisions

This page covers basic concepts how to use this gem. If you need more complex examples check integration tests please.

To start using the gem install it. Add this line to your application's Gemfile:

gem "yaso"

And then execute:

bundle install

Or install it yourself as:

gem install yaso

Create a service class and inherit it from Yaso::Service (I will use controller show action as an example):

module Users
  class Show < Yaso::Service
  end
end

Implement your business logic, e. g. "Find user":

module Users
  class Show < Yaso::Service
    step :model

    def model(ctx, params:, **)
      ctx[:model] = User.find_by(id: params[:id])
    end
  end
end

Step declares what method to run and method contains your code that should be executed. When your step returns anything truthy (not nil or false) step is treated as succeeded otherwise as failed. It's a base concept of flow manipulation. If step fails flow will execute the next failure step or stop execution and return failed context if there is no failure steps. If step succeeds the next step is executed or execution is stoped and succeeded context is returned if there is no more steps.

You can access things from the context in 2 ways:

Via context

def model(ctx, **)
  id = ctx[:params][:id]
  ctx[:model] = User.find_by(id: id)
end

As a named parameter. Be aware while using this type because parameter should exist inside the context or you will get an error. Provide a default value or use the way above if you're not sure that value is inside the context.

def model(ctx, params:, **)
  ctx[:model] = User.find_by(id: params[:id])
end

Now when you can execute your service:

Users::Show.call(params: {id: 1})
# => returns service instance as a result with all the data that were added to `ctx` during invocation

And now you can check execution went successfully or not:

# Succeeds if user was found
result = Users::Show.call(params: {id: 1})
# => Result:Users::Show successful: true, context: {:model=>#<User:0x000000010d644250>}

result.success? # => true
result.failure? # => false

# Fails if user wasn't found
result = Users::Show.call(params: {id: 1})
# => Result:Users::Show successful: false, context: {:model=>nil}

result.success? # => false
result.failure? # => true

And access data that were added to the context:

result = Users::Show.call(params: {id: 1})
# => Result:Users::Show successful: true, context: {:model=>#<User:0x000000010d644250>}

result[:model] # => #<User:0x000000010d644250>

Now lets add a failure step to handle the use-case when user wasn't found:

module Users
  class Show < Yaso::Service
    step :model
    failure :not_found

    def model(ctx, params:, **)
      ctx[:model] = User.find_by(id: params[:id])
    end

    def not_found(ctx, params:, **)
      ctx[:error] = "User with id=#{params[:id]} does not exist"
    end
  end
end

And when you execute the service:

# Succeeds if user was found
result = Users::Show.call(params: {id: 1})
# => Result:Users::Show successful: true, context: {:model=>#<User:0x000000010d644250>}


# Fails if user wasn't found
result = Users::Show.call(params: {id: 1})
# => Result:Users::Show successful: false, context: {:model=>nil, :error=>"User with id=1 does not exist"}

And that's it.

Clone this wiki locally