aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/lib/action_mailer/railtie.rb2
-rw-r--r--actionmailer/lib/action_mailer/railties/routes_helpers.rb12
-rw-r--r--actionpack/lib/action_controller/base.rb8
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb6
-rw-r--r--actionpack/lib/action_controller/railtie.rb3
-rw-r--r--actionpack/lib/action_controller/railties/routes_helpers.rb17
-rw-r--r--railties/lib/rails/engine.rb9
-rw-r--r--railties/test/railties/engine_test.rb129
8 files changed, 182 insertions, 4 deletions
diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb
index c888e51b93..26fe125fd8 100644
--- a/actionmailer/lib/action_mailer/railtie.rb
+++ b/actionmailer/lib/action_mailer/railtie.rb
@@ -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 @@ module ActionMailer
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
diff --git a/actionmailer/lib/action_mailer/railties/routes_helpers.rb b/actionmailer/lib/action_mailer/railties/routes_helpers.rb
new file mode 100644
index 0000000000..3464ec38e2
--- /dev/null
+++ b/actionmailer/lib/action_mailer/railties/routes_helpers.rb
@@ -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
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 7a1464c2aa..3560ac5b8c 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -223,9 +223,13 @@ module ActionController
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 \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 4b6897c5dd..c5d7842db3 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -101,8 +101,12 @@ module ActionController
# 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
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 7496dd57b2..23622b19e8 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -4,6 +4,7 @@ require "action_dispatch/railtie"
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 @@ module ActionController
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
diff --git a/actionpack/lib/action_controller/railties/routes_helpers.rb b/actionpack/lib/action_controller/railties/routes_helpers.rb
new file mode 100644
index 0000000000..a23f703f0b
--- /dev/null
+++ b/actionpack/lib/action_controller/railties/routes_helpers.rb
@@ -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
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 85ff09d2af..7f53e2dc72 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -199,6 +199,15 @@ module Rails
@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
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index d4ecdf4742..db610451bd 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -298,5 +298,134 @@ module RailtiesTest
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