Permalink
Browse files

Include application's helpers and router helpers by default, but incl…

…ude engine's ones for controllers inside isolated namespace
  • Loading branch information...
1 parent 9913193 commit c7664d112fadb313146da33f48d1da318f249927 @drogus drogus committed Jul 30, 2010
@@ -1,5 +1,6 @@
require "action_mailer"
require "rails"
+require "action_mailer/railties/routes_helpers"
module ActionMailer
class Railtie < Rails::Railtie
@@ -20,6 +21,7 @@ class Railtie < Rails::Railtie
ActiveSupport.on_load(:action_mailer) do
include app.routes.url_helpers
include app.routes.mounted_helpers(:app)
+ extend ::ActionMailer::Railties::RoutesHelpers
options.each { |k,v| send("#{k}=", v) }
end
end
@@ -0,0 +1,12 @@
+module ActionMailer
+ module Railties
+ module RoutesHelpers
+ def inherited(klass)
+ super(klass)
+ if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
+ klass.send(:include, namespace._railtie.routes.url_helpers)
+ end
+ end
+ end
+ end
+end
@@ -223,9 +223,13 @@ def self.without_modules(*modules)
def self.inherited(klass)
super
- klass.helper :all if klass.superclass == ActionController::Base
+ if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
+ klass.helper(all_helpers_from_path(namespace._railtie.config.paths.app.helpers.to_a))
+ else
+ klass.helper :all if klass.superclass == ActionController::Base
+ end
end
ActiveSupport.run_load_hooks(:action_controller, self)
end
-end
+end
@@ -101,8 +101,12 @@ def modules_for_helpers(args)
# Extract helper names from files in <tt>app/helpers/**/*_helper.rb</tt>
def all_application_helpers
+ all_helpers_from_path(helpers_path)
+ end
+
+ def all_helpers_from_path(path)
helpers = []
- Array.wrap(helpers_path).each do |path|
+ Array.wrap(path).each do |path|
extract = /^#{Regexp.quote(path.to_s)}\/?(.*)_helper.rb$/
helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
@@ -4,6 +4,7 @@
require "action_view/railtie"
require "active_support/deprecation/proxy_wrappers"
require "active_support/deprecation"
+require "action_controller/railties/routes_helpers"
module ActionController
class Railtie < Rails::Railtie
@@ -50,7 +51,7 @@ class Railtie < Rails::Railtie
options.helpers_path ||= paths.app.helpers.to_a
ActiveSupport.on_load(:action_controller) do
- include app.routes.url_helpers
+ extend ::ActionController::Railties::RoutesHelpers.with(app.routes)
include app.routes.mounted_helpers(:app)
options.each { |k,v| send("#{k}=", v) }
end
@@ -0,0 +1,17 @@
+module ActionController
+ module Railties
+ module RoutesHelpers
+ def self.with(routes)
+ Module.new do
+ define_method(:inherited) do |klass|
+ super(klass)
+ if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
+ routes = namespace._railtie.routes
+ end
+ klass.send(:include, routes.url_helpers)
+ end
+ end
+ end
+ end
+ end
+end
@@ -199,6 +199,15 @@ def endpoint(endpoint = nil)
@endpoint = endpoint if endpoint
@endpoint
end
+
+ def isolated_engine_for(mod)
+ _engine = self
+ mod.singleton_class.instance_eval do
+ define_method(:_railtie) do
+ _engine
+ end
+ end
+ end
end
delegate :middleware, :root, :paths, :to => :config
@@ -298,5 +298,134 @@ class Engine < ::Rails::Engine
response = Rails.application.call(env)
assert_equal response[2].path, File.join(@plugin.path, "public/bukkits.html")
end
+
+ test "shared engine should include application's helpers" do
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do
+ match "/foo" => "bukkits/foo#index", :as => "foo"
+ match "/foo/show" => "bukkits/foo#show"
+ end
+ RUBY
+
+ app_file "app/helpers/some_helper.rb", <<-RUBY
+ module SomeHelper
+ def something
+ "Something... Something... Something..."
+ end
+ end
+ RUBY
+
+ @plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY
+ class Bukkits::FooController < ActionController::Base
+ def index
+ render :inline => "<%= something %>"
+ end
+
+ def show
+ render :text => foo_path
+ end
+ end
+ RUBY
+
+ boot_rails
+
+ env = Rack::MockRequest.env_for("/foo")
+ response = Rails.application.call(env)
+ assert_equal "Something... Something... Something...", response[2].body
+
+ env = Rack::MockRequest.env_for("/foo/show")
+ response = Rails.application.call(env)
+ assert_equal "/foo", response[2].body
+ end
+
+ test "isolated engine should include only its own routes and helpers" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ isolated_engine_for Bukkits
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do
+ match "/bar" => "bar#index", :as => "bar"
+ mount Bukkits::Engine => "/bukkits", :as => "bukkits"
+ end
+ RUBY
+
+ @plugin.write "config/routes.rb", <<-RUBY
+ Bukkits::Engine.routes.draw do
+ match "/foo" => "bukkits/foo#index", :as => "foo"
+ match "/foo/show" => "bukkits/foo#show"
+ match "/from_app" => "bukkits/foo#from_app"
+ match "/routes_helpers_in_view" => "bukkits/foo#routes_helpers_in_view"
+ end
+ RUBY
+
+ app_file "app/helpers/some_helper.rb", <<-RUBY
+ module SomeHelper
+ def something
+ "Something... Something... Something..."
+ end
+ end
+ RUBY
+
+ @plugin.write "app/helpers/engine_helper.rb", <<-RUBY
+ module EngineHelper
+ def help_the_engine
+ "Helped."
+ end
+ end
+ RUBY
+
+ @plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY
+ class Bukkits::FooController < ActionController::Base
+ def index
+ render :inline => "<%= help_the_engine %>"
+ end
+
+ def show
+ render :text => foo_path
+ end
+
+ def from_app
+ render :inline => "<%= (self.respond_to?(:bar_path) || self.respond_to?(:something)) %>"
+ end
+
+ def routes_helpers_in_view
+ render :inline => "<%= foo_path %>, <%= app.bar_path %>"
+ end
+ end
+ RUBY
+
+ @plugin.write "app/mailers/bukkits/my_mailer.rb", <<-RUBY
+ module Bukkits
+ class MyMailer < ActionMailer::Base
+ end
+ end
+ RUBY
+
+ boot_rails
+
+ assert_equal Bukkits._railtie, Bukkits::Engine
+ assert ::Bukkits::MyMailer.method_defined?(:foo_path)
+
+ env = Rack::MockRequest.env_for("/bukkits/from_app")
+ response = AppTemplate::Application.call(env)
+ assert_equal "false", response[2].body
+
+ env = Rack::MockRequest.env_for("/bukkits/foo/show")
+ response = AppTemplate::Application.call(env)
+ assert_equal "/bukkits/foo", response[2].body
+
+ env = Rack::MockRequest.env_for("/bukkits/foo")
+ response = AppTemplate::Application.call(env)
+ assert_equal "Helped.", response[2].body
+
+ env = Rack::MockRequest.env_for("/bukkits/routes_helpers_in_view")
+ response = AppTemplate::Application.call(env)
+ assert_equal "/bukkits/foo, /bar", response[2].body
+ end
end
end

0 comments on commit c7664d1

Please sign in to comment.