# Dynamic Controller Creation in Rails

I have overrode Rails' ActionDispatch::Routing::RouteSet::Dispatcher.controller_reference method to check if a controller exists by checking for the required constants and then creating them based upon a controller with the same name in the Generic namespace.

The problem w/ my code is that it is using begin/rescue, it won't work w/ deeply namespaced controllers, and it's rather verbose.

Can anyone provide some improvements to this code?

class ActionDispatch::Routing::RouteSet::Dispatcher

private

def controller_reference(controller_param)
const_name = @controller_class_names[controller_param] ||= "#{controller_param.camelize}Controller"

obj = Object
const_name.split('::').each do |cn|
begin
obj =  obj.const_get(cn)
rescue
if obj == Object
obj =  obj.const_set(cn, Class.new(ApplicationController))
else
puts "Creating #{obj}::#{cn} based on Generic::#{cn}"
obj =  obj.const_set(cn, Class.new("Generic::#{cn}".constantize))
end
end
end

ActiveSupport::Dependencies.constantize(const_name)
end

end

• you can use const_defined? instead of the begin/rescue, the rest looks just fine... :-) – Uri Agassi Apr 26 '14 at 15:05
• I think this code is good, but it's better to catch only NameError to avoid suppressing errors not related to this patch. – ka8725 Feb 9 '18 at 14:07

Disclaimer: this should be a comment, my reputation at the moment does not allow me to comment your question

What about exploiting const_missing? https://apidock.com/ruby/Module/const_missing

I used it in an app to declare ActiveRecord models at runtime. If you are interested in this approach I suggest you to namespace all Dynamic controllers i.e.

module Dyn
def self.const_missing(sym)
# Declare class Dyn::MyDynamicController
# without overriding or patching Rails classes
end
end