URL Helpers module is reset after initialization in 3.2.9 #8488

Closed
semaperepelitsa opened this Issue Dec 11, 2012 · 5 comments

Projects

None yet

2 participants

@semaperepelitsa

My Rails plugin modifies url_for method so that :locale option is converted to the appropriate subdomain. See https://github.com/semaperepelitsa/subdomain_locale/blob/master/lib/subdomain_locale/url_for.rb

In a railtie I include this module into Rails.application.routes.url_helpers for zero-setup. See
https://github.com/semaperepelitsa/subdomain_locale/blob/master/lib/subdomain_locale/railtie.rb

This broke in 3.2.9. I see that Rails.application.routes.url_helpers module changes after initialization and therefore no longer includes my module. The breaking commit might be this one by @spastorino: e41d78c.

What is the way to accomplish the same thing now?

@pixeltrix
Ruby on Rails member

You can use the to_prepare method of your Railtie's config to add a block that's called every time the routes are reloaded, e.g.

require "rails/railtie"
require "subdomain_locale/controller"
require "subdomain_locale/url_for"

module SubdomainLocale
  class Railtie < ::Rails::Railtie
    config.to_prepare do
      ::Rails.application.routes.url_helpers.send :include, SubdomainLocale::UrlFor
    end

    initializer "subdomain_locale.controller" do
      ActiveSupport.on_load :action_controller do
        include SubdomainLocale::Controller
      end
    end
  end
end

The above code isn't tested but it should be something like that - if you can't get it to work please let me know.

@semaperepelitsa

This doesn't work until I touch some file (in development).

I'm logging URL helper module in to_prepare block and it's ancestors in controller's before filter.
At the server's boot to_prepare block is executed once. When loading a page I see a different module logged.

to prepare #<Module:0x007fd8424a5cc8>
[#<Module:0x007fd7ce2fdac0>]

Refreshing the page logs the same ancestors: [#<Module:0x007fd7ce2fdac0>].

After touching a file to_prepare block is executed one more time and this time I get the correct module on all subsequent requests:

to prepare
#<Module:0x007fd7ce2fdac0>
[#<Module:0x007fd7ce2fdac0>, SubdomainLocale::UrlFor]

Looks like to_prepare block is called too early at the start.

@pixeltrix
Ruby on Rails member

@semaperepelitsa I've just tested this code using a fork of your gem which seems to work, can you let me know whether it works everywhere you expect it to:

require "rails/railtie"

module SubdomainLocale
  class Railtie < ::Rails::Railtie

    initializer "subdomain_locale.url_helpers", :after => :set_routes_reloader_hook do
      require "subdomain_locale/url_for"
      Rails.application.routes.url_helpers.send :include, SubdomainLocale::UrlFor

      ActionDispatch::Reloader.to_prepare do
        Rails.application.routes.url_helpers.send :include, SubdomainLocale::UrlFor
      end
    end

    initializer "subdomain_locale.controller" do
      ActiveSupport.on_load :action_controller do
        require "subdomain_locale/controller"
        include SubdomainLocale::Controller
      end
    end

  end
end

I'm leaving this open for the moment as I'm investigating a bit more about route reloading and what needs to be cleared.

@pixeltrix pixeltrix was assigned Dec 12, 2012
@semaperepelitsa

This messes up asset server. I'm not sure how this can be related. Commenting out the initializer and restarting makes it go back to normal.

Started GET "/assets/application.css" for 127.0.0.1 at 2012-12-12 18:46:27 +0800

ActionController::RoutingError (No route matches [GET] "/assets/application.css"):
  .bundle/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  .bundle/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  .bundle/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/logger.rb:32:in `call_app'
  .bundle/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/logger.rb:16:in `block in call'
  .bundle/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/tagged_logging.rb:22:in `tagged'
  .bundle/ruby/1.9.1/gems/railties-3.2.9/lib/rails/rack/logger.rb:16:in `call'
  .bundle/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/request_id.rb:22:in `call'
  .bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/methodoverride.rb:21:in `call'
  .bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/runtime.rb:17:in `call'
  .bundle/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  .bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/lock.rb:15:in `call'
  .bundle/ruby/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/static.rb:62:in `call'
  .bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward'
  .bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:245:in `fetch'
  .bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:185:in `lookup'
  .bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:66:in `call!'
  .bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call'
  .bundle/ruby/1.9.1/gems/railties-3.2.9/lib/rails/engine.rb:479:in `call'
  .bundle/ruby/1.9.1/gems/railties-3.2.9/lib/rails/application.rb:223:in `call'
  .bundle/ruby/1.9.1/gems/railties-3.2.9/lib/rails/railtie/configurable.rb:30:in `method_missing'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:147:in `handle'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:99:in `rescue in block (2 levels) in start'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:96:in `block (2 levels) in start'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:86:in `each'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:86:in `block in start'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:66:in `loop'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:66:in `start'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:13:in `run'
  /Users/sema/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/bin/nack_worker:4:in `<main>'
@pixeltrix
Ruby on Rails member

Hmm, even an empty initializer breaks assets - I'll look at this again.

@pixeltrix pixeltrix added a commit that closed this issue Dec 14, 2012
@pixeltrix pixeltrix Clear url helper methods when routes are reloaded
Clear url helper methods when routes are reloaded by removing the
methods explicitly rather than just clearing the module because it
didn't work properly and could be the source of a memory leak.

Closes #8488.
6ab1a95
@pixeltrix pixeltrix closed this in 6ab1a95 Dec 14, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment