The right way to override render method

Hi there, I’m writing a controller concern for HTMX.

I need to override ActionController::Base.render method, but I don’t know if this it’s the right way:

  def render(*args, &block)
    options = _normalize_render(*args, &block)

    # Set flash now
    if (_flash_now = options.delete :flash_now)
      _flash_now.each do |type, text|
        flash.now[type] = text
      end
    end

    # Set headers
    if (_headers = options.delete :headers)
      _headers.each do |header, value|
        response.headers[header] = value
      end
    end

    # Avoid layout when HTMX Request
    options[:layout] = false if hx_request?

    super options, &block
  end

I search on internet and I can’t find anything about this. There are a best way to implement this?

Gracias|Thanks.

Instead of overriding render, it might be better to use formats and set things other ways. Your best bet is to take a look at the turbo_rails gem, since it also checks if requests are coming from turbo to change how rendering will be performed.

For example, here is how it handles the special layout for frames. Just rename what you need and replace turbo_frame_request? with hx_request?

module HtmxRequest
  extend ActiveSupport::Concern

  included do
    layout -> { "turbo_rails/frame" if turbo_frame_request? }
    etag { :frame if turbo_frame_request? }

    helper_method :turbo_frame_request_id
  end

  private
    def turbo_frame_request?
      turbo_frame_request_id.present?
    end

    def turbo_frame_request_id
      request.headers["Turbo-Frame"]
    end
end

And this is how it handles both a normal response and a stream response.

def destroy
  @user.destroy!

  respond_to do |format|
    format.turbo_stream { render turbo_stream: turbo_stream.remove(@user) }
    format.html         { redirect_to users_url, notice: "User removed" }
  end
end