8
\$\begingroup\$

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

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.