### Activate Plugin in Pathway Operation Source: https://github.com/mayesa/pathway/blob/master/README.md Shows how to activate a plugin in a Pathway operation class. Plugins can be activated with parameters and are inherited by subclasses, similar to Roda or Sequel plugins. ```ruby class BaseOperation < Pathway::Operation plugin :foobar, qux: 'quz' end class SomeOperation < BaseOperation # The :foobar plugin will also be activated here end ``` -------------------------------- ### Invoke Pathway operation with class call (Ruby) Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates alternative syntax for invoking a Pathway operation directly on the class, passing the context and input parameters. ```ruby user = User.first(session[:current_user_id]) context = { current_user: user } CreateNugget.call(context, params[:nugget]) # Using 'call' on the class ``` -------------------------------- ### Add authorization step using SimpleAuth plugin in Pathway Source: https://github.com/mayesa/pathway/blob/master/README.md Illustrates how to include the SimpleAuth plugin, define an authorization predicate, and insert an :authorize step that halts the operation with a :forbidden error if the predicate fails. Requires Pathway and the simple_auth plugin. ```ruby class MyOperation < Pathway::Operation plugin :simple_auth context :current_user authorization { current_user.is_admin? } process do step :authorize step :perform_some_action end # ... end ``` -------------------------------- ### Load Pathway RSpec Matchers in Ruby Source: https://github.com/mayesa/pathway/blob/master/README.md This snippet shows how to load Pathway's RSpec matchers in your spec helper file. It is essential for testing operations with the provided matchers. ```ruby require 'pathway/rspec' ``` -------------------------------- ### Handle operation outcomes with Responder plugin in Pathway Source: https://github.com/mayesa/pathway/blob/master/README.md Illustrates the Responder plugin for flow control based on success or failure of an operation. The first example provides generic success/failure handling, while the second uses pattern‑matched failure cases for more granular error responses. Both snippets require calling MyOperation.plugin :responder. ```Ruby MyOperation.plugin :responder # 'plugin' is actually a public method MyOperation.(context, params) do success { |value| r.halt(200, value.to_json) } # BTW: 'r.halt' is a Roda request method used to exemplify failure { |error| r.halt(403) } end ``` ```Ruby MyOperation.plugin :responder MyOperation.(context, params) do success { |value| r.halt(200, value.to_json) } failure(:forbidden) |error| r.halt(403) } failure(:validation) { |error| r.halt(422, error.details.to_json) } failure(:not_found) { |error| r.halt(404) } end ``` -------------------------------- ### Initialize Pathway operation with context (Ruby) Source: https://github.com/mayesa/pathway/blob/master/README.md Illustrates how to define and use initialization context in a Pathway operation. The context method is used to declare mandatory and optional context parameters. ```ruby class CreateNugget < Pathway::Operation context :current_user, notify: false def call(input) validation = Validator.call(input) if validation.valid? nugget = Nugget.create(owner: current_user, **validation.values) Notifier.notify(:new_nugget, nugget) if @notify success(nugget) else error(:validation, message: 'Invalid input', details: validation.errors) end end end op = CreateNugget.new(current_user: user) op.call(foo: 'foobar') ``` -------------------------------- ### Configure SequelModels plugin for Pathway Source: https://github.com/mayesa/pathway/blob/master/README.md Shows two ways to a Sequel model with Pathway operations using the SequelModels plugin: (1) passing model and options directly to the plugin declaration, and (2) declaring the model later with the model DSL. Both approaches enable custom steps for model lookup and result handling. Requires Pathway and the sequel gem. ```ruby class MyOperation < Pathway::Operation plugin :sequel_models, model: Nugget, search_by: :name, set_result_key: false end ``` ```ruby class MyOperation < Pathway::Operation plugin :sequel_models # This is useful when using inheritance and you need different models per operation model Nugget, search_by: :name, set_result_key: false process do step :authorize step :perform_some_action end end ``` -------------------------------- ### Define Pathway Operation in Ruby Source: https://github.com/mayesa/pathway/blob/master/README.md This Ruby class demonstrates a Pathway operation with steps for authorization, validation, nugget creation, and notification. It uses context for current user, processes input through steps, and sets the result at a specified key. ```ruby class CreateNugget < Pathway::Operation context :current_user process do step :authorize step :validate set :create_nugget step :notify end result_at :nugget def authorize(*) unless current_user.can? :create, Nugget error(:forbidden) end end def validate(state) validation = NuggetForm.call(state[:input]) if validation.ok? state[:params] = validation.values else error(:validation, details: validation.errors) end end def create_nugget(:params, **) Nugget.create(owner: current_user, **params) end def notify(:nugget, **) Notifier.notify(:new_nugget, nugget) end end ``` -------------------------------- ### Implement a Pathway operation using manual Result handling (Ruby) Source: https://github.com/mayesa/pathway/blob/master/README.md Shows how to create a plain Ruby the Pathway function object protocol by manually constructing Pathway::Result objects for success and failure. Requires the Pathway gem and a Repository service. Input is passed to the call method and the result object provides success?, value, and error methods. ```ruby class MyFirstOperation def call(input) result = Repository.create(input) if result.valid? Pathway::Result.success(result) else way::Result.failure(:create_error) end end end result = MyFirstOperation.new.call(foo: 'foobar') if result.success? puts result.value.inspect else puts "Error: #{result.error}" end ``` -------------------------------- ### Define a Pathway Operation in Ruby Source: https://github.com/mayesa/pathway/blob/master/README.md This code defines a Pathway operation with dry-validation plugin, including parameter validation and a process block to create a nugget. ```ruby class CreateNugget < Pathway::Operation { plugin :dry_validation params do { required(:owner).filled(:string) required(:price).filled(:integer) optional(:disabled).maybe(:bool) } process do { step :validate set :create_nugget } def create_nugget(params:,**) { Nugget.create(params) } } ``` -------------------------------- ### Wrap steps in transaction and after_commit blocks in Pathway operation Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates using the transaction and after_commit DSL methods to run multiple steps inside a database transaction and execute follow‑up steps only after a successful commit. This ensures atomicity of the main steps and deferred actions like sending emails. Requires the sequel_models plugin and a SEQUEL_DB connection. ```Ruby class CreateNugget < Pathway::Operation plugin :sequel_models, model: Nugget process do step :validate transaction do step :create_nugget step :attach_history_note after_commit do step :send_emails end end end # ... end ``` -------------------------------- ### Test Pathway Operation with RSpec in Ruby Source: https://github.com/mayesa/pathway/blob/master/README.md This RSpec test demonstrates how to test a Pathway operation using the provided matchers like `succeed_on`, `fail_on`, and contract matchers. ```ruby describe CreateNugget do { describe '#call' do { subject(:operation) { CreateNugget.new } context 'when the input is valid' do { let(:input) { owner: 'John Smith', value: '11230' } it { is_expected.to succeed_on(input).returning(an_instace_of(Nugget)) } } context 'when the input is invalid' do { let(:input) { owner: '', value: '11230' } it { is_expected.to fail_on(input). with_type(:validation). message('Is not valid'). and_details(owner: ['must be present']) } } } describe '.contract' do { subject(:contract) { CreateNugget.build_contract } it { is_expected.to require_fields(:owner, :price) } it { is_expected.to accept_optional_field(:disabled) } } } ``` -------------------------------- ### Define operation process steps with Ruby DSL Source: https://github.com/mayesa/pathway/blob/master/README.md Shows how to use the process DSL to define operation steps within a Pathway Operation class. The DSL automatically generates the call method and manages execution flow. Steps can be defined using 'step' for actions or 'set' for value assignments. ```ruby # Inside an operation class body... process do step :authorize step :validate set :create_nugget, to: :nugget step :notify end ``` -------------------------------- ### ActiveRecord Plugin in Ruby Source: https://github.com/mayesa/pathway/blob/master/README.md This Ruby plugin for Pathway provides basic ActiveRecord integration, allowing operations to fetch models by primary key and execute steps within database transactions. It defines class methods for setting model and primary key, instance methods for state manipulation, and DSL methods for transaction wrapping. Limitations include incompatibility with Sequel plugin and dependency on ActiveRecord gem; inputs are operation states with model data, outputs are updated states or errors. ```ruby module Pathway module Plugins module ActiveRecord module ClassMethods attr_accessor :model, :pk def inherited(subclass) super subclass.model = self.model subclass.pk = self.pk end end module InstanceMethods delegate :model, :pk, to: :class # This method will conflict with :sequel_models so you mustn't load both plugins in the same operation def fetch_model(state, column: pk) current_pk = state[:input][column] result = model.first(column => current_pk) if result state.update(result_key => result) else error(:not_found) end end end module DSLMethods # This method also conflicts with :sequel_models, so don't use them at once def transaction(&steps) transactional_seq = -> seq, _state do ActiveRecord::Base.transaction do raise ActiveRecord::Rollback if seq.call.failure? end end around(transactional_seq, &steps) end end def self.apply(operation, model: nil, pk: nil) operation.model = model opertaion.pk = pk || model&.primary_key end end end end ``` -------------------------------- ### Access operation state with Ruby hash destructuring Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates how to access operation execution state using Ruby's hash destructuring syntax. Methods can cherry-pick needed attributes while ignoring others using the double splat operator. ```ruby # This step only takes the values it needs and doesn't change the state. def send_emails(user:, report:, **) ReportMailer.send_report(user.email, report) end ``` -------------------------------- ### Implement a Pathway operation by subclassing Pathway::Operation (Ruby) Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates using the Pathway::Operation base class to simplify result handling with helper methods success and failure. Inherits from Pathway::Operation, reducing boilerplate. Requires the Pathway gem and a Repository service. The call method returns a Result object based on validation. ```ruby class MyFirstOperation < Pathway::Operation def call(input) result = Repository.create(input) result.valid? ? success(result) : failure(:create_error) end end ``` -------------------------------- ### Manually map state attributes to dry-validation contract options Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates using the dry-validation plugin without auto-wiring and explicitly mapping a state attribute to a contract option via the with: hash on the validate step. Useful when the context key and contract option names differ. Requires Pathway and dry-validation. ```ruby class CreateNugget < Pathway::Operation plugin :dry_validation context :current_user_name contract do option :user_name params do required(:owner).filled(:string) required(:price).filled(:integer) end rule(:owner) do key.failure("invalid owner") unless user_name == values[:owner] end end process do step :validate, with: { user_name: :current_user_name } # Inject :user_name to the contract object with the state's :current_user_name step :create_nugget end # ... end ``` -------------------------------- ### Create error in Pathway operation (Ruby) Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates how to create and return an error in a Pathway operation. The error method is used with type, message, and details parameters. The error is automatically wrapped in a Pathway::Failure. ```ruby class CreateNugget < Pathway::Operation def call(input) validation = Validator.call(input) if validation.ok? success(Nugget.create(validation.values)) else error(:validation, message: 'Invalid input', details: validation.errors) end end end ``` -------------------------------- ### Access error details in Pathway (Ruby) Source: https://github.com/mayesa/pathway/blob/master/README.md Shows how to access the type, message, and details of an error from a failed Pathway operation result. The error object is accessed via the result.error method. ```ruby result = CreateNugget.new.call(foo: 'foobar') if result.failure? puts "#{result.error.type} error: #{result.error.message}" puts "Error details: #{result.error.details}" end ``` -------------------------------- ### Fetch model within Pathway operation using :fetch_model step Source: https://github.com/mayesa/pathway/blob/master/README.md Shows how to retrieve a database model inside a Pathway operation using the :fetch_model step. The step can be customized with from, using, search_by, and to options to control the source class, input key, search column, and result attribute. Requires the sequel_models plugin and returns the fetched record in the operation result. ```Ruby class UpdateNugget < Pathway::Operation plugin :sequel_models, model: Nugget process do step :validate step :fetch_model step :fetch_model, from: User, using: :user_id, search_by: :pk, to: :user # Even the default class can also be overrided with 'from:' step :update_nugget end # ... end ``` -------------------------------- ### Enable auto-wired options for dry-validation contract in Pathway Source: https://github.com/mayesa/pathway/blob/master/README.md Shows how to activate the dry-validation plugin with auto_wire_options set to true, allowing contract options to be automatically pulled from the operation's context. Requires Pathway and dry-validation >= 1.0. The operation validates owner against the provided user_name option. ```ruby class CreateNugget < Pathway::Operation plugin :dry_validation, auto_wire_options: true context :user_name contract do option :user_name params do required(:owner).filled(:string) required(:price).filled(:integer) end rule(:owner) do key.failure("invalid owner") unless user_name == values[:owner] end end process do step :validate step :create_nugget end # ... end ``` -------------------------------- ### Integrating DryValidation Plugin in Pathway Operations Source: https://github.com/mayesa/pathway/blob/master/README.md Demonstrates how to set up and use the dry-validation plugin in Pathway operations for input validation. Requires the dry-validation gem and Pathway framework. It takes input data, validates against defined contracts, and returns errors if validation fails. Variations include defining contracts as classes, inline blocks, or directly with params, useful for simple validations but requires understanding of dry-validation API. ```ruby class NuggetContract < Dry::Validation::Contract params do required(:owner).filled(:string) required(:price).filled(:integer) end end class CreateNugget < Pathway::Operation plugin :dry_validation contract NuggetContract process do step :validate step :create_nugget end # ... end ``` ```ruby class CreateNugget < Pathway::Operation plugin :dry_validation contract do params do required(:owner).filled(:string) required(:price).filled(:integer) end end process do step :validate step :create_nugget end # ... end ``` ```ruby class CreateNugget < Pathway::Operation plugin :dry_validation params do required(:owner).filled(:string) required(:price).filled(:integer) end process do step :validate step :create_nugget end # ... end ``` -------------------------------- ### Create Basic Operation with Pathway Ruby Gem Source: https://context7.com/mayesa/pathway/llms.txt Defines a simple operation subclass that creates a repository record and returns a success or failure result. Demonstrates invoking the operation and handling the resulting value or error. Requires the Pathway gem and a Repository implementation. ```ruby class MyFirstOperation < Pathway::Operation def call(input) result = Repository.create(input) result.valid? ? success(result) : failure(:create_error) end end result = MyFirstOperation.new.call(foo: 'foobar') if result.success? puts result.value.inspect else puts "Error: #{result.error}" end ``` -------------------------------- ### Compose Operations with Process Steps Source: https://context7.com/mayesa/pathway/llms.txt Defines a multi‑step operation using the `process` block, declaring ordered steps, state mapping, and a final result extraction point. Includes implementations for authorization, validation, creation, and notification. ```ruby class CreateNugget < Pathway::Operation context :current_user process do step :authorize step :validate set :create_nugget, to: :nugget step :notify end result_at :nugget def authorize(*) unless current_user.can?(:create, Nugget) error(:forbidden) end end def validate(state) validation = NuggetForm.call(state[:input]) if validation.ok? state[:params] = validation.values error(:validation, details: validation.errors) end end def create_nugget(params:, **) Nugget.create(owner: current_user, **params) end def notify(nugget:, **) Notifier.notify(:new_nugget, nugget) end end result = CreateNugget.call( { current_user: user }, { owner: 'John', price: 100 } ) ``` -------------------------------- ### Invoke Operations via Class-Level Call Syntax Source: https://context7.com/mayesa/pathway/llms.txt Illustrates calling an operation directly on its class with a context hash, using both the standard `.call` method and the shorthand `.` syntax. Also shows invoking operations with an empty context when none is required. ```ruby user = User.first(session[:current_user_id]) context = { current_user: user, notify: true } # Call directly on the class result = CreateNugget.call(context, params[:nugget]) # Alternative syntax result = CreateNugget.(context, params[:nugget]) # Empty context when not needed result = SimpleOperation.call({}, input_data) ``` -------------------------------- ### Generate Success and Failure Result Objects Source: https://context7.com/mayesa/pathway/llms.txt Shows how to create explicit success and failure Result objects using Pathway::Result, inspect their state, and integrate them within an operation. Useful for standardizing return values across the application. ```ruby # Creating success results success_result = Pathway::Result.success({ id: 1, name: "Test" }) success.success? # => true success_result.value # => { id: 1, name: "Test" } # Creating failure results failure_result = Pathway::Result.failure(:validation_failed) failure_result.failure? # => true failure_result.success? # => false failure_result.error # => :validation_failed # Using with operations class CheckAge < Pathway::Operation def call(input) age = input[:age] age >= 18 ? success(true) : failure(:underage) end end result = CheckAge.new.call(age: 16) puts result.error if result.failure? # => :underage ``` -------------------------------- ### Apply DryValidation Plugin for Input Validation Source: https://context7.com/mayesa/pathway/llms.txt Shows enabling the `:dry_validation` plugin, declaring a contract with required and optional parameters, and wiring a validation step into the process pipeline. The operation returns a success result when input passes validation. ```ruby class CreateNugget < Pathway::Operation plugin :dry_validation params do required(:owner).filled(:string) required(:price).filled(:integer) optional(:disabled).maybe(:bool) end process do step :validate set :create_nugget end def create_nugget(params:, **) Nugget.create(params) end end # Valid input result = CreateNugget.call({}, { owner: 'John Smith', price: 11230 }) result.success? # => true ``` -------------------------------- ### Set Context Values During Operation Initialization Source: https://context7.com/mayesa/pathway/llms.txt Uses the `context` macro to declare injectable values such as the current user and a notification flag. Shows initializing an operation with these values and accessing them inside the call method. ```ruby class CreateNugget < Pathway::Operation context :current_user, notify: false def call(input) validation = Validator.call(input) if validation.valid? nugget = Nugget.create(owner: current_user, **validation.values) Notifier.notify(:new_nugget, nugget) if @notify success(nugget) else error(:validation, message: 'Invalid input', details: validation.errors) end end end # Initialize with context user = User.first(session[:current_user_id]) op = CreateNugget.new(current_user: user, notify: true) result = op.call(foo: 'foobar') ``` -------------------------------- ### ActiveRecord Plugin for Pathway Operations (Ruby) Source: https://context7.com/mayesa/pathway/llms.txt Defines an ActiveRecord plugin for Pathway operations, enabling model association, primary key handling, and transactional operations. It allows operations to interact with ActiveRecord models, fetch data, and manage database transactions. ```ruby module Pathway module Plugins module ActiveRecord module ClassMethods attr_accessor :model, :pk def inherited(subclass) super subclass.model = self.model subclass.pk = self.pk end end module InstanceMethods delegate :model, :pk, to: :class def fetch_model(state, column: pk) current_pk = state[:input][column] result = model.where(column => current_pk).first result ? state.update(result_key => result) : error(:not_found) end end module DSLMethods def transaction(&steps) transactional_seq = -> seq, _state do ActiveRecord::Base.transaction do raise ActiveRecord::Rollback if seq.call.failure? end end around(transactional_seq, &steps) end end def self.apply(operation, model: nil, pk: nil) operation.model = model operation.pk = pk || model&.primary_key end end end end # Using the custom plugin class UpdatePost < Pathway::Operation plugin :active_record, model: Post process do step :fetch_model transaction do step :update_post end end def update_post(post:, **) post.update(title: "Updated") post end end ``` -------------------------------- ### RSpec Testing for Pathway Operations (Ruby) Source: https://context7.com/mayesa/pathway/llms.txt Demonstrates RSpec tests for a Pathway operation using custom matchers. It covers testing successful execution, failure scenarios with specific error types and details, and contract validation requirements. ```ruby require 'pathway/rspec' describe CreateNugget do subject(:operation) { CreateNugget.new(current_user: user) } let(:user) { User.create(name: 'John') } context 'when input is valid' do let(:input) { { owner: 'John Smith', price: 11230 } } it { is_expected.to succeed_on(input).returning(an_instance_of(Nugget)) } end context 'when input is invalid' do let(:input) { { owner: '', price: 11230 } } it { is_expected.to fail_on(input) .with_type(:validation) .message('Invalid input') .and_details(owner: ['must be filled']) } end describe '.contract' do subject(:contract) { CreateNugget.build_contract } it { is_expected.to require_fields(:owner, :price) } it { is_expected.to accept_optional_field(:disabled) } end end ``` -------------------------------- ### Define Structured Error Objects in Operations Source: https://context7.com/mayesa/pathway/llms.txt Demonstrates constructing detailed error objects with type message, and arbitrary details, then accessing these attributes after an operation fails. Allows richer error reporting for callers. ```ruby class CreateNugget < Pathway::Operation def call(input) validation = Validator.call(input) if validation.ok? success(Nugget.create(validation.values)) else error(:validation, message: 'Invalid input', details: validation.errors) end end end result = CreateNugget.new.call(foo: 'invalid') if result.failure? puts "#{result.error.type} error: #{result.error.message}" # => "validation error: Invalid input" puts "Details: #{result.error.details}" # => "Details: { foo: ['is invalid'] }" end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.