Controllers with the same name in different namespaces

Discussion in 'Ruby/Rails' started by thijs, Jan 27, 2008.

  1. thijs

    thijs New Member

    I've been having trouble getting a controller in a namespace with the same name as a controller in the root namespace. A simplified version of the code:
    Code:
    ActionController::Routing::Routes.draw do |map|
    
      map.resources :editions
    
      map.namespace :organizer do |organizer|
        organizer.resources :editions
      end
    
    end
    
    class EditionsController < ApplicationController
    
      def index
      end
    
    end
    
    class Organizer::EditionsController < ApplicationController
    
      def index
      end
    
    end
    
    /editions shows the EditionsController#index action, but /organizer/editions shows the same EditionsController#index action. Rails does not seem to recognize the namespace in this url.

    This might well be a bug in Rails, we have some similar trouble running the specs in some situations. But this example does work well in Mongrel on our local machines.

    Litespeed consistently routes the namespaced url to the root controller. Do you have any idea what could be the cause of this problem?
  2. mistwang

    mistwang LiteSpeed Staff

    The only difference is that LiteSpeed only set a few Environment variable, not everyone in the shell, if you the route depends on some special environment variable, it must be set under "ruby rails" tab.
    For example, "HOME" must be set when use RESTful route.
  3. Grzegorz Derebecki

    Grzegorz Derebecki New Member

    I have the same problem :)

    When i do /opt/lsws/bin/lswsctrl restart

    my Movie:HomeController isn't used but it use HomeController

    But when i killall -9 ruby and litespeed start it from begining it start working ok.

    of corse doing /opt/lsws/bin/lswsctrl restart we have problem again :)


    PS. on apache i don't have problems with this :)
    Last edited: Jan 28, 2008
  4. Grzegorz Derebecki

    Grzegorz Derebecki New Member

    I find solution (i hope - becous errors can back ;-))

    I used Rails preload controllers

    Code:
    if RAILS_ENV == 'production'
      require_dependency 'application'
      require_dependency 'movie/base'
      require_dependency 'admin/base'
      
      Dir.foreach( "#{RAILS_ROOT}/app/models" ) {|f| $logger.d "r #{f}"; silence_warnings{require_dependency f} if f =~ /\.rb$/}
      
      Dir.foreach( "#{RAILS_ROOT}/app/controllers/movie" ) {|f| $logger.d "r #{f}"; silence_warnings{require_dependency f} if f =~ /\.rb$/}
      Dir.foreach( "#{RAILS_ROOT}/app/controllers/admin" ) {|f| $logger.d "r #{f}"; silence_warnings{require_dependency f} if f =~ /\.rb$/}
      Dir.foreach( "#{RAILS_ROOT}/app/controllers" ) {|f| $logger.d "r #{f}"; silence_warnings{require_dependency f} if f =~ /\.rb$/}
     
    end
    
    PS. $logger isn't working for rails 2.x
  5. mistwang

    mistwang LiteSpeed Staff

    Does $logger work for rails 2.x when WEBrick or mongrel is used?

    Another main difference of Ruby LSAPI is that it forks children processes off a process with initialized Rails framework, I am not sure it is the cause or not.
  6. Grzegorz Derebecki

    Grzegorz Derebecki New Member


    >> $logger
    => nil

    it don't even works in console :)
    http://wiki.rubyonrails.org/rails/pages/logger
    This is just for controler, model, mailer. Maybe logger is initialized after environment, don't know :)

    Maybe forked children are problem..

    I don't found many simillar isuses only this one http://www.ruby-forum.com/topic/125392

    This error is very hard to reproduce becous sometimes it takes many request before it happends.
  7. mistwang

    mistwang LiteSpeed Staff

    I think it maybe related to ruby internal bugs, as I remember, there are bug related to popen() or other functions use fork() then exec(), if exec() failed, the forked children process does not shutdown properly.
  8. thijs

    thijs New Member

    I've been doing a bit more research. I've traced the problem to constantize and finally to Object.module_eval

    If you replace your constantize method in active_support/lib/inflector.rb with this to get some logging:

    Code:
    def constantize(camel_cased_word)
        unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
          raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
        end
        
        result = Object.module_eval("::#{$1}", __FILE__, __LINE__)
        RAILS_DEFAULT_LOGGER.error("constantize '#{camel_cased_word}', result: '#{result}'") if camel_cased_word.ends_with?('Controller')
        result
      end
    
    You'll see the module_eval sometimes returns the class in the module, and sometimes it doesn't:

    My output when the processes have just been restarted is:

    constantize 'Organizer::EditionsController', result: 'Organizer::EditionsController'

    But later when the error occurs the log output is:

    constantize 'Organizer::EditionsController', result: 'EditionsController'

    This seems to be a problem in Ruby then?
  9. thijs

    thijs New Member

    Thanks Grzegorz, you're suggestion seems to be fixing the issue. I've modified it a bit for Rails 2.0:

    Code:
    controller_dir = "#{RAILS_ROOT}/app/controllers"
    Dir.foreach(controller_dir) { |f| silence_warnings { require_dependency("#{controller_dir}/#{f}") } if f =~ /\.rb$/ }
    Dir.foreach("#{controller_dir}/organizer") { |f| silence_warnings { require_dependency("#{controller_dir}/organizer/#{f}") } if f =~ /\.rb$/ }
    
  10. Grzegorz Derebecki

    Grzegorz Derebecki New Member

    at first require_dependency is bad, becous it is alias to load with meens that ruby will always reload our class and don't cache it.


    I think that i found some solutions about this here:

    http://peat.wordpress.com/2006/06/30/watch-your-namespace/

    I had movie model, and movie::home controller (movie/home) and i think this was problem:)


    thijs maby you have model organizer ? if yes just change namespace from organizer to organizers and it should works ok.
  11. mistwang

    mistwang LiteSpeed Staff

    I am not a RoR expert at all, but from a generic programming point of view, the route matching algorithm should try to match the longest path when possible, maybe change the routing configuration order can help.
  12. Grzegorz Derebecki

    Grzegorz Derebecki New Member

    i'm not RoR expert too but i think this is not routing foul.

    models in rails look like:
    class Foo < ActiveRecord:Base
    end


    controllers
    class FooController < ApplicationController
    end


    but if we define namespace controller

    class Foo::TestController < ApplicationController
    end

    we are in model namespace ;-) i think this is problem.

Share This Page