aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose and Yehuda <wycats@gmail.com>2012-04-25 16:06:20 -0500
committerYehuda Katz <wycats@gmail.com>2012-04-25 16:07:17 -0500
commit6acebb38bc0637bc05c19d87f8767f16ce79189b (patch)
treee37fa39f516e16c1d36e3b5202e9231c56aa4305
parent3c100cfe8ed5a875b0bbdc8fa4e8f2b0cbf78676 (diff)
downloadrails-6acebb38bc0637bc05c19d87f8767f16ce79189b.tar.gz
rails-6acebb38bc0637bc05c19d87f8767f16ce79189b.tar.bz2
rails-6acebb38bc0637bc05c19d87f8767f16ce79189b.zip
Allow loading external route files from the router
This feature enables the ability to load an external routes file from the router via: draw :filename External routes files go in +config/routes+. This feature works in both engines and applications.
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb16
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb2
-rw-r--r--guides/source/routing.textile18
-rw-r--r--railties/lib/rails/engine.rb3
-rw-r--r--railties/lib/rails/engine/configuration.rb3
-rw-r--r--railties/lib/rails/paths.rb12
-rw-r--r--railties/test/application/paths_test.rb2
-rw-r--r--railties/test/application/routing_test.rb24
-rw-r--r--railties/test/paths_test.rb2
9 files changed, 79 insertions, 3 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index fdc0bfb686..716e2d2271 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1305,6 +1305,21 @@ module ActionDispatch
parent_resource.instance_of?(Resource) && @scope[:shallow]
end
+ def draw(name)
+ path = @draw_paths.find do |path|
+ path.join("#{name}.rb").file?
+ end
+
+ unless path
+ msg = "Your router tried to #draw the external file #{name}.rb,\n" \
+ "but the file was not found in:\n\n"
+ msg += @draw_paths.map { |path| " * #{path}" }.join("\n")
+ raise msg
+ end
+
+ instance_eval(path.join("#{name}.rb").read)
+ end
+
# match 'path' => 'controller#action'
# match 'path', to: 'controller#action'
# match 'path', 'otherpath', on: :member, via: :get
@@ -1554,6 +1569,7 @@ module ActionDispatch
def initialize(set) #:nodoc:
@set = set
+ @draw_paths = set.draw_paths
@scope = { :path_names => @set.resources_path_names }
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index f1aa131cbb..7a7810a95c 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -255,6 +255,7 @@ module ActionDispatch
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
attr_accessor :disable_clear_and_finalize, :resources_path_names
attr_accessor :default_url_options, :request_class, :valid_conditions
+ attr_accessor :draw_paths
alias :routes :set
@@ -266,6 +267,7 @@ module ActionDispatch
self.named_routes = NamedRouteCollection.new
self.resources_path_names = self.class.default_resources_path_names.dup
self.default_url_options = {}
+ self.draw_paths = []
self.request_class = request_class
@valid_conditions = {}
diff --git a/guides/source/routing.textile b/guides/source/routing.textile
index 5e1cc042dc..836e0cdd70 100644
--- a/guides/source/routing.textile
+++ b/guides/source/routing.textile
@@ -829,6 +829,24 @@ end
This will create routing helpers such as +magazine_periodical_ads_url+ and +edit_magazine_periodical_ad_path+.
+h3. Breaking Up a Large Route File
+
+If you have a large route file that you would like to break up into multiple files, you can use the +#draw+ method in your router:
+
+<ruby>
+draw :admin
+</ruby>
+
+Then, create a file called +config/routes/admin.rb+. Name the file the same as the symbol passed to the +draw+ method). You can then use the normal routing DSL inside that file:
+
+<ruby>
+# in config/routes/admin.rb
+
+namespace :admin do
+ resources :posts
+end
+</ruby>
+
h3. Inspecting and Testing Routes
Rails offers facilities for inspecting and testing your routes.
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 43ee396cbe..3b302b23a7 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -487,6 +487,7 @@ module Rails
def routes
@routes ||= ActionDispatch::Routing::RouteSet.new
+ @routes.draw_paths.concat paths["config/routes"].paths
@routes.append(&Proc.new) if block_given?
@routes
end
@@ -544,7 +545,7 @@ module Rails
end
initializer :add_routing_paths do |app|
- paths = self.paths["config/routes"].existent
+ paths = self.paths["config/routes.rb"].existent
if routes? || paths.any?
app.routes_reloader.paths.unshift(*paths)
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index d7405cb519..9f7c5f8704 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -52,7 +52,8 @@ module Rails
paths.add "config/environments", :glob => "#{Rails.env}.rb"
paths.add "config/initializers", :glob => "**/*.rb"
paths.add "config/locales", :glob => "*.{rb,yml}"
- paths.add "config/routes", :with => "config/routes.rb"
+ paths.add "config/routes.rb"
+ paths.add "config/routes", :glob => "**/*.rb"
paths.add "db"
paths.add "db/migrate"
paths.add "db/seeds", :with => "db/seeds.rb"
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index dd1790299d..fced6f8896 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -1,3 +1,5 @@
+require "pathname"
+
module Rails
module Paths
# This object is an extended hash that behaves as root of the <tt>Rails::Paths</tt> system.
@@ -114,7 +116,7 @@ module Rails
class Path
include Enumerable
- attr_reader :path
+ attr_reader :path, :root
attr_accessor :glob
def initialize(root, current, paths, options = {})
@@ -180,6 +182,14 @@ module Rails
@paths
end
+ def paths
+ raise "You need to set a path root" unless @root.path
+
+ map do |p|
+ Pathname.new(@root.path).join(p)
+ end
+ end
+
# Expands all paths against the root and return all unique values.
def expanded
raise "You need to set a path root" unless @root.path
diff --git a/railties/test/application/paths_test.rb b/railties/test/application/paths_test.rb
index 4029984ce9..e0893f53be 100644
--- a/railties/test/application/paths_test.rb
+++ b/railties/test/application/paths_test.rb
@@ -50,6 +50,8 @@ module ApplicationTests
assert_path @paths["config/locales"], "config/locales/en.yml"
assert_path @paths["config/environment"], "config/environment.rb"
assert_path @paths["config/environments"], "config/environments/development.rb"
+ assert_path @paths["config/routes.rb"], "config/routes.rb"
+ assert_path @paths["config/routes"], "config/routes"
assert_equal root("app", "controllers"), @paths["app/controllers"].expanded.first
end
diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb
index 204f43a442..1dac086119 100644
--- a/railties/test/application/routing_test.rb
+++ b/railties/test/application/routing_test.rb
@@ -166,6 +166,30 @@ module ApplicationTests
assert_equal 'WIN', last_response.body
end
+ test "routes drawing from config/routes" do
+ app_file 'config/routes.rb', <<-RUBY
+ AppTemplate::Application.routes.draw do
+ draw :external
+ end
+ RUBY
+
+ app_file 'config/routes/external.rb', <<-RUBY
+ get ':controller/:action'
+ RUBY
+
+ controller :success, <<-RUBY
+ class SuccessController < ActionController::Base
+ def index
+ render :text => "success!"
+ end
+ end
+ RUBY
+
+ app 'development'
+ get '/success/index'
+ assert_equal 'success!', last_response.body
+ end
+
{"development" => "baz", "production" => "bar"}.each do |mode, expected|
test "reloads routes when configuration is changed in #{mode}" do
controller :foo, <<-RUBY
diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb
index d334034e7d..aa04cad033 100644
--- a/railties/test/paths_test.rb
+++ b/railties/test/paths_test.rb
@@ -29,6 +29,7 @@ class PathsTest < ActiveSupport::TestCase
test "creating a root level path" do
@root.add "app"
assert_equal ["/foo/bar/app"], @root["app"].to_a
+ assert_equal [Pathname.new("/foo/bar/app")], @root["app"].paths
end
test "creating a root level path with options" do
@@ -191,6 +192,7 @@ class PathsTest < ActiveSupport::TestCase
@root["app"] = "/app"
@root["app"].glob = "*.rb"
assert_equal "*.rb", @root["app"].glob
+ assert_equal [Pathname.new("/app")], @root["app"].paths
end
test "it should be possible to override a path's default glob without assignment" do