Last Updated: September 27, 2021
·
4.364K
· fdeschenes

BeforeRender Concern for Rails

Here's a simple before_render concern which can be used to run callbacks right before a view is rendered.

In app/controllers/application_controller.rb, add include BeforeRender and then use before_render to set the callbacks.

class ApplicationController < ActionController::Base
    include BeforeRender

    before_render :set_layout

    def set_layout
        # ...
    end
end

Create app/controllers/concerns/before_render.rb and add the code below.

 module BeforeRender
    extend ActiveSupport::Concern

    included do
        alias_method_chain :render, :before_render_action
        define_callbacks :render
    end

    def render_with_before_render_action(*options, &block)
        run_callbacks :render do
            render_without_before_render_action *options, &block
        end
    end

    module ClassMethods
        def append_before_render_action(*names, &block)
            _insert_callbacks(names, block) do |name, options|
                set_callback :render, :before, name, options
            end
        end

        def prepend_before_render_action(*names, &block)
            _insert_callbacks(names, block) do |name, options|
                set_callback :render, :before, name, options.merge(:prepend => true)
            end
        end

        def skip_before_render_action(*names, &block)
            _insert_callbacks(names, block) do |name, options|
                skip_callback :render, :before, name, options
            end
        end

        alias_method :before_render, :append_before_render_action
        alias_method :prepend_before_render, :prepend_before_render_action
        alias_method :skip_before_render, :skip_before_render_action
    end
end

That's it!

4 Responses
Add your response

Exactly what I needed. Thank you!

over 1 year ago ·

Thanks. I think this should be in Rails. Did you PR that?

over 1 year ago ·

Thanks so much!

over 1 year ago ·

This is great. It even follows standard rails conventions, so I can use :only and :except, like:

whitelabel_pages = [:new]
before_render whitelabel, only: whitelabel_pages
over 1 year ago ·