Skip to content

Intercepting parent controller rendering

apotonick edited this page Jan 31, 2013 · 2 revisions

It can be useful to inject behavior into a Rails controller that is reused across multiple controllers. This can be achieved with cells.

class MyController < ApplicationController

  before_filter :check_user_input

  def check_user_input
    @user_input = Cell::Rails.create_cell_for("hijacker",self).render_state :ask_user_once
  end

  def show
    ... # do something that requires @user_input
  end
end


class Hijacker < Cell::Rails
  def ask_user_once
    # just an example, no need to store it in the session
    session[:user_input] = params[:input_we_need] if params.key?(:input_we_need)
    return session[:user_input] if session[:user_input]
    parent_controller.render :text => render, :layout => true
    return nil
  end
end

The trick is to call the parent controller's render method in a before filter, which prevents the main action from being rendered. To return the cell's own view the output of the cell's render method has to be passed as text output to the parent's render method.

--EDIT apotonick: I find it a bit dangerous to call the controller's #render method from outside. The cell state could return a special value which is then used as a decider in the before_filter, where the actual rendering happens.