1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Include application's helpers and router helpers by default, but include engine's ones for controllers inside isolated namespace

This commit is contained in:
Piotr Sarnacki 2010-07-30 07:14:48 +02:00
parent 9913193931
commit c7664d112f
8 changed files with 182 additions and 4 deletions

View file

@ -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

View file

@ -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

View file

@ -223,8 +223,12 @@ module ActionController
def self.inherited(klass)
super
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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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