Tag: Ruby

Removing a particular middleware from Sinatra based Ruby application

From time to time, you may want to remove a particular middleware from your Sinatra application. Normally I would not recommend this, but when you test stuff and play around there might be no other way. It is also useful when a middleware contains bugs that make it unusable in your particular case. Removing it is really easy. Only thing you need to know is the name of the middleware you want to remove:

Sidekiq::Web.instance_variable_get(:@middleware).delete_if do |middleware|
  middleware.first == Rack::Protection # Or any other middleware name
end

Rails + Responders + Trailblazer – Flash messages with proper model names from Trailblazer operations

Responders gem is really awesome. It sets flash message based on the controller action and resource status allowing you to dry up your Rails controllers. Trailblazer is a thin layer on top of Rails. It gently enforces encapsulation, an intuitive code structure and gives you an object-oriented architecture. When combining both of them together, you can achieve really slim and functional controllers:

class ContractsController < BaseController
  def index
    respond_with(collection Contracts::Index)
  end

  def show
    respond_with(present Contracts::Update)
  end

  def new
    respond_with(form Contracts::Create)
  end

  def create
    respond_with(run Contracts::Create)
  end

  def edit
    respond_with(form Contracts::Update)
  end

  def update
    respond_with(run Contracts::Update)
  end

  def destroy
    respond_with(run Contracts::Destroy)
  end
end

Unfortunately there's one downside: Since Responders #respond_with method expects a model as a first argument, it will think that your operation is a model (if you return it the way I did) and try to figure out it's human name. Probably it won't end up as you expect and you will see a message similar to this one:

Users/campaigns/update was successfully updated.

It happens because of this piece of code from Responders:

resource_name = if resource.class.respond_to?(:model_name)
  resource.class.model_name.human
else
  resource.class.name.underscore.humanize
end

Trailblazer operations don't respond to #model_name, that's why all the operations will be translated using the else statement. To make it work as expected, we just need to implement the #model_name class method:

class ApplicationOperation < Trailblazer::Operation
  def self.model_name
    ::ActiveModel::Name.new(model_class)
  end
end

I follow the ApplicationController, ApplicationRecord, ApplicationHelper "pattern" also with operations. That way I don't need to add this code into Trailblazer::Operation or into each of the operations separately. #model_class method is a method that will return the model class that we've set using Trailblazer::Operation #method:

class Operation < ApplicationOperation
 include Model
 model Contract
end

Operation.model_class #=> Contract
Operation.model_name #=> ActiveModel::Name:0x0000000575b778 @name="Contract"...

From now on, all the Trailblazer operations will introduce themselves to Responders with the name of the model on which we operate.

Copyright © 2025 Closer to Code

Theme by Anders NorenUp ↑