controller
- 1.0.0
- 1.1.6
- 1.2.6
- 2.0.3
- 2.1.0
- 2.2.1
- 2.3.8
- 3.0.0 (0)
- 3.0.9 (-1)
- 3.1.0 (0)
- 3.2.1 (0)
- 3.2.8 (0)
- 3.2.13 (0)
- 4.0.2 (0)
- 4.1.8 (0)
- 4.2.1
- 4.2.7
- 4.2.9
- 5.0.0.1
- 5.1.7
- 5.2.3
- 6.0.0
- 6.1.3.1
- 6.1.7.7
- 7.0.0
- 7.1.3.2
- 7.1.3.4
- What's this?
controller(params, default_controller=true)
public
If this is a default_controller (i.e. a controller specified by the user) we should raise an error in case it’s not found, because it usually means an user error. However, if the controller was retrieved through a dynamic segment, as in :controller(/:action), we should simply return nil and delegate the control back to Rack cascade. Besides, if this is not a default controller, it means we should respect the @scope[:module] parameter.
How to handle dynamic controller class evaluation based on params
Possible with following snippet of code (for instance if each branch has some different controller logic, but if the controller is not present, it should fallback to default controller).
Advantages are so we do not have to make blank inherited controllers and routes for them, to do it with plain inheritance.
class ActionDispatch::Routing::RouteSet::CustomDispatcher < ActionDispatch::Routing::RouteSet::Dispatcher # These are the controllers that we should attempt fallbacks on FALLBACK_CONTROLLERS = /customer\/branch\/(projects|events)$/ def controller(params, default_controller=true) # This defines when we want to attempt fallbacks pattern super unless params[:branch_id] && params[:controller].try(:match, FALLBACK_CONTROLLERS) controller_param = params[:controller] # Having these supplied, we handle controller evaluation by our own method... controller_reference_with_fallbacks(params[:branch_id], controller_param) rescue NameError => e raise ActionController::RoutingError, e.message, e.backtrace if default_controller end private def controller_reference_with_fallbacks(branch_id, controller_param) # This is how fallbacks are evaluated controller_name = "#{controller_param.sub('/branch', "/branch/#{branch_id}").camelize}Controller" controller = ActiveSupport::Dependencies.reference(controller_name) begin controller.get(controller_name) rescue NameError => e # If there is no specific class for given branch, fallback to original class controller_reference(controller_param) end end end ActionDispatch::Routing::Mapper::Mapping.class_eval do private # We do overwrite dispatcher class, that is used to evaluate controller classes from params def app ActionDispatch::Routing::Mapper::Constraints.new( to.respond_to?(:call) ? to : ::ActionDispatch::Routing::RouteSet::CustomDispatcher.new(:defaults => defaults), blocks, @set.request_class ) end end