提交 1ba22bcd 编写于 作者: J José Valim

Merge remote branch 'drogus/engines'

require 'rack/mount'
require 'forwardable'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/hash/slice'
module ActionDispatch
module Routing
......@@ -511,7 +512,7 @@ def url_for(options)
end
script_name = options.delete(:script_name)
path = (script_name.blank? ? _generate_prefix(options) : script_name).to_s
path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s
path_options = options.except(*RESERVED_OPTIONS)
path_options = yield(path_options) if block_given?
......
require 'abstract_unit'
require 'rack/test'
module TestGenerationPrefix
class Post
extend ActiveModel::Naming
def to_param
"1"
end
def self.model_name
klass = "Post"
def klass.name; self end
ActiveModel::Name.new(klass)
end
end
class WithMountedEngine < ActionDispatch::IntegrationTest
require 'rack/test'
include Rack::Test::Methods
class BlogEngine
......@@ -55,21 +70,6 @@ def self.call(env)
# force draw
RailsApplication.routes
class Post
extend ActiveModel::Naming
def to_param
"1"
end
def self.model_name
klass = "Post"
def klass.name; self end
ActiveModel::Name.new(klass)
end
end
class ::InsideEngineGeneratingController < ActionController::Base
include BlogEngine.routes.url_helpers
include RailsApplication.routes.mounted_helpers
......@@ -253,4 +253,65 @@ def setup
assert_equal "http://www.example.com/awesome/blog/posts/1", path
end
end
class EngineMountedAtRoot < ActionDispatch::IntegrationTest
include Rack::Test::Methods
class BlogEngine
def self.routes
@routes ||= begin
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
match "/posts/:id", :to => "posts#show", :as => :post
end
routes
end
end
def self.call(env)
env['action_dispatch.routes'] = routes
routes.call(env)
end
end
class RailsApplication
def self.routes
@routes ||= begin
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
mount BlogEngine => "/"
end
routes
end
end
def self.call(env)
env['action_dispatch.routes'] = routes
routes.call(env)
end
end
# force draw
RailsApplication.routes
class ::PostsController < ActionController::Base
include BlogEngine.routes.url_helpers
include RailsApplication.routes.mounted_helpers
def show
render :text => post_path(:id => params[:id])
end
end
def app
RailsApplication
end
test "generating path inside engine" do
get "/posts/1"
assert_equal "/posts/1", last_response.body
end
end
end
......@@ -13,7 +13,7 @@ module ActiveRecord
class Railtie < Rails::Railtie
config.active_record = ActiveSupport::OrderedOptions.new
config.generators.orm :active_record, :migration => true,
config.app_generators.orm :active_record, :migration => true,
:timestamps => true
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
......
......@@ -39,6 +39,7 @@ class Application < Engine
autoload :Configuration, 'rails/application/configuration'
autoload :Finisher, 'rails/application/finisher'
autoload :Railties, 'rails/application/railties'
autoload :RoutesReloader, 'rails/application/routes_reloader'
class << self
def inherited(base)
......@@ -81,17 +82,7 @@ def eager_load! #:nodoc:
end
def routes_reloader
@routes_reloader ||= ActiveSupport::FileUpdateChecker.new([]){ reload_routes! }
end
def reload_routes!
_routes = self.routes
_routes.disable_clear_and_finalize = true
_routes.clear!
routes_reloader.paths.each { |path| load(path) }
ActiveSupport.on_load(:action_controller) { _routes.finalize! }
ensure
_routes.disable_clear_and_finalize = false
@routes_reloader ||= RoutesReloader.new
end
def initialize!
......
......@@ -24,6 +24,7 @@ def initialize(*)
@time_zone = "UTC"
@middleware = app_middleware
@asset_path = '/'
@generators = app_generators
end
def asset_path=(value)
......
module Rails
class Application
class RoutesReloader < ::ActiveSupport::FileUpdateChecker
def initialize
super([]) { reload! }
end
def blocks
@blocks ||= {}
end
private
def reload!
clear!
load_blocks
load_paths
finalize!
ensure
revert
end
def clear!
routers.each do |routes|
routes.disable_clear_and_finalize = true
routes.clear!
end
end
def load_blocks
blocks.each do |routes, block|
routes.draw(&block) if block
end
end
def load_paths
paths.each { |path| load(path) }
end
def finalize!
routers.each do |routes|
ActiveSupport.on_load(:action_controller) { routes.finalize! }
end
end
def revert
routers.each do |routes|
routes.disable_clear_and_finalize = false
end
end
def routers
blocks.keys
end
end
end
end
......@@ -11,7 +11,17 @@
command = aliases[command] || command
case command
when 'generate', 'destroy', 'plugin', 'benchmarker', 'profiler'
when 'generate', 'destroy', 'plugin'
require APP_PATH
Rails.application.require_environment!
if defined?(ENGINE_PATH)
engine = Rails.application.railties.engines.find { |r| r.root.to_s == ENGINE_PATH }
Rails.application = engine
end
require "rails/commands/#{command}"
when 'benchmarker', 'profiler'
require APP_PATH
Rails.application.require_environment!
require "rails/commands/#{command}"
......@@ -23,8 +33,13 @@
Rails::Console.start(Rails.application)
when 'server'
# try to guess application's path if there is no config.ru file in current dir
# it allows to run script/rails server from other directories
Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
require 'rails/commands/server'
Rails::Server.new.tap { |server|
# we need to require application after the server sets environment
require APP_PATH
Dir.chdir(Rails.application.root)
server.start
......
......@@ -333,21 +333,22 @@ def endpoint(endpoint = nil)
def namespace(mod)
engine_name(generate_railtie_name(mod))
_railtie = self
name = engine_name
mod.singleton_class.instance_eval do
define_method(:_railtie) do
_railtie
end
define_method(:table_name_prefix) do
"#{name}_"
end
end
self.routes.default_scope = {:module => name}
self.namespaced = true
unless mod.respond_to?(:_railtie)
_railtie = self
mod.singleton_class.instance_eval do
define_method(:_railtie) do
_railtie
end
define_method(:table_name_prefix) do
"#{name}_"
end
end
end
end
def namespaced?
......@@ -398,8 +399,10 @@ def env_config
}
end
def routes
def routes(&block)
@routes ||= ActionDispatch::Routing::RouteSet.new
self.routes_draw_block = block if block_given?
@routes
end
def initializers
......@@ -446,6 +449,7 @@ def load_seed
end
initializer :add_routing_paths do |app|
app.routes_reloader.blocks[routes] = routes_draw_block
paths.config.routes.to_a.each do |route|
app.routes_reloader.paths.unshift(route) if File.exists?(route)
end
......@@ -498,6 +502,8 @@ def load_seed
end
protected
attr_accessor :routes_draw_block
def find_root_with_flag(flag, default=nil)
root_path = self.class.called_from
......
......@@ -17,6 +17,19 @@ def app_middleware
@@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
end
# This allows you to modify application's generators from Railties.
#
# Values set on app_generators will become defaults for applicaiton, unless
# application overwrites them.
def app_generators
@@app_generators ||= Rails::Configuration::Generators.new
if block_given?
yield @@app_generators
else
@@app_generators
end
end
# Holds generators configuration:
#
# config.generators do |g|
......@@ -30,11 +43,11 @@ def app_middleware
# config.generators.colorize_logging = false
#
def generators
@@generators ||= Rails::Configuration::Generators.new
@generators ||= Rails::Configuration::Generators.new
if block_given?
yield @@generators
yield @generators
else
@@generators
@generators
end
end
......
module Rails
class TestUnitRailtie < Rails::Railtie
config.generators do |c|
config.app_generators do |c|
c.test_framework :test_unit, :fixture => true,
:fixture_replacement => nil
......
......@@ -643,5 +643,104 @@ class Engine < ::Rails::Engine
Bukkits::Engine.load_seed
assert Bukkits::Engine.config.bukkits_seeds_loaded
end
test "using namespace more than once on one module should not overwrite _railtie method" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module AppTemplate
class Engine < ::Rails::Engine
namespace(AppTemplate)
end
end
RUBY
add_to_config "namespace AppTemplate"
app_file "config/routes.rb", <<-RUBY
AppTemplate::Application.routes.draw do end
RUBY
boot_rails
assert_equal AppTemplate._railtie, AppTemplate::Engine
end
test "properly reload routes" do
# when routes are inside application class definition
# they should not be reloaded when engine's routes
# file has changed
add_to_config <<-RUBY
routes do
mount lambda{|env| [200, {}, ["foo"]]} => "/foo"
mount Bukkits::Engine => "/bukkits"
end
RUBY
FileUtils.rm(File.join(app_path, "config/routes.rb"))
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
mount lambda{|env| [200, {}, ["bar"]]} => "/bar"
end
RUBY
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
class Engine < ::Rails::Engine
namespace(Bukkits)
end
end
RUBY
require 'rack/test'
extend Rack::Test::Methods
boot_rails
require "#{rails_root}/config/environment"
get "/foo"
assert_equal "foo", last_response.body
get "/bukkits/bar"
assert_equal "bar", last_response.body
end
test "setting generators for engine and overriding app generator's" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
class Engine < ::Rails::Engine
config.generators do |g|
g.orm :datamapper
g.template_engine :haml
g.test_framework :rspec
end
config.app_generators do |g|
g.orm :mongoid
g.template_engine :liquid
g.test_framework :shoulda
end
end
end
RUBY
add_to_config <<-RUBY
config.generators do |g|
g.test_framework :test_unit
end
RUBY
boot_rails
require "#{rails_root}/config/environment"
app_generators = Rails.application.config.generators.options[:rails]
assert_equal :mongoid , app_generators[:orm]
assert_equal :liquid , app_generators[:template_engine]
assert_equal :test_unit, app_generators[:test_framework]
generators = Bukkits::Engine.config.generators.options[:rails]
assert_equal :datamapper, generators[:orm]
assert_equal :haml , generators[:template_engine]
assert_equal :rspec , generators[:test_framework]
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册