[フレーム]
Last Updated: February 25, 2016
·
1.366K
· miguelff

Dynamically define and mount rails controller once the application has started

# Install controller action in the given route
# implementing the behavior in the block provided
#
# install_controller! 'auth/callback' do
# render text: params[:code]
# end
#
# the former is equivalent to mounting in 'auth/callback' 
# route the following controller:
#
# class AuthController < ApplicationController
# def callback
# render text: params[:code]
# end
# end
#
# To avoid collisions, you can also specify the controller 
# and action to use:
#
# install_controller! 'auth/callback', 'sessions#inspect' do
# sessions[:code] = params[:code]
# head :ok
# end
#
# Which will be equivalent as mounting in the 'auth/callback' 
# route this controller:
#
# class SessionsController < ApplicationController
# def inspect
# sessions[:code] = params[:code]
# head :ok
# end
# end
#
def install_controller!(route, controller_action = nil, &b)
 controller_action ||= route.sub('/','#')
 controller, action = controller_action.split('#')

 klass = Class.new(ApplicationController) do
 define_method action.to_sym, &b
 end

 self.class.const_set "#{controller.classify}Controller", klass

 Rails.application.routes.tap do |routes|
 begin
 routes.disable_clear_and_finalize = true
 routes.clear!
 Rails.application.routes_reloader.paths.each { |path| load(path) }
 routes.draw do
 match route, to: controller_action, via: [:get, :post]
 end
 ActiveSupport.on_load(:action_controller) { routes.finalize! }
 ensure
 routes.disable_clear_and_finalize = false
 end
 end
end

AltStyle によって変換されたページ (->オリジナル) /