diff options
author | José Valim <jose.valim@gmail.com> | 2009-12-01 13:00:34 -0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-12-01 13:00:34 -0200 |
commit | c2e97cb410d759f383d29920165abdbf4b70e019 (patch) | |
tree | b375de84add24ee4c4551deec533b0667512bf34 /actionpack | |
parent | fc3629f6ca2b43693f5447a1fb43881f1814e117 (diff) | |
parent | 6ac32a83283f46b55675ddf4ecab6c91f6f8abde (diff) | |
download | rails-c2e97cb410d759f383d29920165abdbf4b70e019.tar.gz rails-c2e97cb410d759f383d29920165abdbf4b70e019.tar.bz2 rails-c2e97cb410d759f383d29920165abdbf4b70e019.zip |
Merge branch 'master' of git://github.com/rails/rails
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/actionpack.gemspec | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 279 | ||||
-rw-r--r-- | actionpack/lib/action_view.rb | 2 | ||||
-rw-r--r-- | actionpack/test/controller/caching_test.rb | 4 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing_test.rb | 8 |
6 files changed, 195 insertions, 102 deletions
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index ccf6bf1e83..936279ad12 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.add_dependency('activemodel', '= 3.0.pre') s.add_dependency('rack', '~> 1.0.1') s.add_dependency('rack-test', '~> 0.5.0') - s.add_dependency('rack-mount', '~> 0.2.2') + s.add_dependency('rack-mount', '~> 0.2.3') s.add_dependency('erubis', '~> 2.6.5') s.require_path = 'lib' diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb index f8f6b424ca..07b4919934 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb @@ -7,7 +7,7 @@ names = traces.collect {|name, trace| name} %> -<p><code>RAILS_ROOT: <%= defined?(RAILS_ROOT) ? RAILS_ROOT : "unset" %></code></p> +<p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p> <div id="traces"> <% names.each do |name| %> diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index cfe7425a61..34d75e55b6 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -2,8 +2,73 @@ module ActionDispatch module Routing class Mapper module Resources + class Resource #:nodoc: + attr_reader :plural, :singular + attr_reader :path_prefix, :name_prefix + + def initialize(entities, options = {}) + entities = entities.to_s + + @plural = entities.pluralize + @singular = entities.singularize + + @path_prefix = options[:path_prefix] + @name_prefix = options[:name_prefix] + end + + def name + plural + end + + def controller + plural + end + + def member_name + if name_prefix + "#{name_prefix}_#{singular}" + else + singular + end + end + + def collection_name + if name_prefix + "#{name_prefix}_#{plural}" + else + plural + end + end + + def new_name + if name_prefix + "new_#{name_prefix}_#{singular}" + else + "new_#{singular}" + end + end + + def edit_name + if name_prefix + "edit_#{name_prefix}_#{singular}" + else + "edit_#{singular}" + end + end + end + + class SingletonResource < Resource #:nodoc: + def initialize(entity, options = {}) + super(entity) + end + + def name + singular + end + end + def resource(*resources, &block) - options = resources.last.is_a?(Hash) ? resources.pop : {} + options = resources.extract_options! if resources.length > 1 raise ArgumentError if block_given? @@ -11,29 +76,31 @@ module ActionDispatch return self end - resource = resources.pop + name_prefix = @scope[:options][:name_prefix] if @scope[:options] + resource = SingletonResource.new(resources.pop, :name_prefix => name_prefix) if @scope[:scope_level] == :resources - member do - resource(resource, options, &block) + parent_resource = @scope[:scope_level_options][:name] + parent_named_prefix = @scope[:scope_level_options][:name_prefix] + with_scope_level(:member) do + scope(":#{parent_resource}_id", :name_prefix => parent_named_prefix) do + resource(resource.name, options, &block) + end end return self end - singular = resource.to_s - plural = singular.pluralize - - controller(plural) do - namespace(resource) do - with_scope_level(:resource) do + controller(resource.controller) do + namespace(resource.name) do + with_scope_level(:resource, :name => resource.singular, :name_prefix => resource.member_name) do yield if block_given? - get "", :to => :show, :as => "#{singular}" + get "", :to => :show, :as => resource.member_name post "", :to => :create put "", :to => :update delete "", :to => :destroy - get "new", :to => :new, :as => "new_#{singular}" - get "edit", :to => :edit, :as => "edit_#{singular}" + get "new", :to => :new, :as => resource.new_name + get "edit", :to => :edit, :as => resource.edit_name end end end @@ -42,7 +109,7 @@ module ActionDispatch end def resources(*resources, &block) - options = resources.last.is_a?(Hash) ? resources.pop : {} + options = resources.extract_options! if resources.length > 1 raise ArgumentError if block_given? @@ -50,42 +117,36 @@ module ActionDispatch return self end - resource = resources.pop - - plural = resource.to_s - singular = plural.singularize + name_prefix = @scope[:options][:name_prefix] if @scope[:options] + resource = Resource.new(resources.pop, :name_prefix => name_prefix) if @scope[:scope_level] == :resources parent_resource = @scope[:scope_level_options][:name] + parent_named_prefix = @scope[:scope_level_options][:name_prefix] with_scope_level(:member) do - scope(":#{parent_resource}_id", :name_prefix => parent_resource) do - resources(resource, options, &block) + scope(":#{parent_resource}_id", :name_prefix => parent_named_prefix) do + resources(resource.name, options, &block) end end return self end - if @scope[:options] && (prefix = @scope[:options][:name_prefix]) - plural = "#{prefix}_#{plural}" - singular = "#{prefix}_#{singular}" - end - - controller(resource) do - namespace(resource) do - with_scope_level(:resources, :name => singular) do + controller(resource.controller) do + namespace(resource.name) do + with_scope_level(:resources, :name => resource.singular, :name_prefix => resource.member_name) do yield if block_given? + collection do + get "", :to => :index, :as => resource.collection_name + post "", :to => :create + get "new", :to => :new, :as => resource.new_name + end + member do - get "", :to => :show, :as => singular + get "", :to => :show, :as => resource.member_name put "", :to => :update delete "", :to => :destroy - get "edit", :to => :edit, :as => "edit_#{singular}" - end - - collection do - get "", :to => :index, :as => plural - post "", :to => :create - get "new", :to => :new, :as => "new_#{singular}" + get "edit", :to => :edit, :as => resource.edit_name end end end @@ -117,7 +178,7 @@ module ActionDispatch end def match(*args) - options = args.last.is_a?(Hash) ? args.pop : {} + options = args.extract_options! args.push(options) case options.delete(:on) @@ -146,8 +207,14 @@ module ActionDispatch end module Scoping + def self.extended(object) + object.instance_eval do + @scope = {} + end + end + def scope(*args) - options = args.last.is_a?(Hash) ? args.pop : {} + options = args.extract_options! constraints = options.delete(:constraints) || {} unless constraints.is_a?(Hash) @@ -193,9 +260,60 @@ module ActionDispatch def constraints(constraints = {}) scope(:constraints => constraints) { yield } end + + def match(*args) + options = args.extract_options! + options = (@scope[:options] || {}).merge(options) + args.push(options) + super(*args) + end + end + + module HttpHelpers + def get(*args, &block) + map_method(:get, *args, &block) + end + + def post(*args, &block) + map_method(:post, *args, &block) + end + + def put(*args, &block) + map_method(:put, *args, &block) + end + + def delete(*args, &block) + map_method(:delete, *args, &block) + end + + def redirect(path, options = {}) + status = options[:status] || 301 + lambda { |env| + req = Rack::Request.new(env) + url = req.scheme + '://' + req.host + path + [status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently']] + } + end + + private + def map_method(method, *args, &block) + options = args.extract_options! + options[:via] = method + args.push(options) + match(*args, &block) + self + end end class Constraints + def new(app, constraints = []) + if constraints.any? + super(app, constraints) + else + app + end + end + def initialize(app, constraints = []) @app, @constraints = app, constraints end @@ -217,34 +335,18 @@ module ActionDispatch def initialize(set) @set = set - @scope = {} + extend HttpHelpers extend Scoping extend Resources end - def get(*args, &block) - map_method(:get, *args, &block) - end - - def post(*args, &block) - map_method(:post, *args, &block) - end - - def put(*args, &block) - map_method(:put, *args, &block) - end - - def delete(*args, &block) - map_method(:delete, *args, &block) - end - def root(options = {}) match '/', options.merge(:as => :root) end def match(*args) - options = args.last.is_a?(Hash) ? args.pop : {} + options = args.extract_options! if args.length > 1 args.each { |path| match(path, options) } @@ -257,7 +359,6 @@ module ActionDispatch path = args.first - options = (@scope[:options] || {}).merge(options) conditions, defaults = {}, {} path = nil if path == "" @@ -289,51 +390,45 @@ module ActionDispatch conditions[:request_method] = Regexp.union(*via) end - defaults[:controller] = @scope[:controller].to_s if @scope[:controller] + defaults[:controller] ||= @scope[:controller].to_s if @scope[:controller] - if options[:to].respond_to?(:call) - app = options[:to] - defaults.delete(:controller) - defaults.delete(:action) - elsif options[:to].is_a?(String) - defaults[:controller], defaults[:action] = options[:to].split('#') - elsif options[:to].is_a?(Symbol) - defaults[:action] = options[:to].to_s + app = initialize_app_endpoint(options, defaults) + validate_defaults!(app, defaults, segment_keys) + app = Constraints.new(app, blocks) + + @set.add_route(app, conditions, requirements, defaults, options[:as]) + + self + end + + private + def initialize_app_endpoint(options, defaults) + app = nil + + if options[:to].respond_to?(:call) + app = options[:to] + defaults.delete(:controller) + defaults.delete(:action) + elsif options[:to].is_a?(String) + defaults[:controller], defaults[:action] = options[:to].split('#') + elsif options[:to].is_a?(Symbol) + defaults[:action] = options[:to].to_s + end + + app || Routing::RouteSet::Dispatcher.new(:defaults => defaults) end - app ||= Routing::RouteSet::Dispatcher.new(:defaults => defaults) - if app.is_a?(Routing::RouteSet::Dispatcher) + def validate_defaults!(app, defaults, segment_keys) + return unless app.is_a?(Routing::RouteSet::Dispatcher) + unless defaults.include?(:controller) || segment_keys.include?("controller") raise ArgumentError, "missing :controller" end + unless defaults.include?(:action) || segment_keys.include?("action") raise ArgumentError, "missing :action" end end - - app = Constraints.new(app, blocks) if blocks.any? - @set.add_route(app, conditions, requirements, defaults, options[:as]) - - self - end - - def redirect(path, options = {}) - status = options[:status] || 301 - lambda { |env| - req = Rack::Request.new(env) - url = req.scheme + '://' + req.host + path - [status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently']] - } - end - - private - def map_method(method, *args, &block) - options = args.last.is_a?(Hash) ? args.pop : {} - options[:via] = method - args.push(options) - match(*args, &block) - self - end end end end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index e95e84aeb5..f6f7ec0c8c 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -25,7 +25,7 @@ require File.join(File.dirname(__FILE__), "action_pack") module ActionView def self.load_all! - [Context, Base, InlineTemplate, TemplateError] + [Context, Base, TemplateError] end autoload :Base, 'action_view/base' diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 3ce90b6ccf..54de920740 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -632,13 +632,15 @@ class FragmentCachingTest < ActionController::TestCase def test_fragment_for_logging fragment_computed = false - ActiveSupport::Notifications.queue.expects(:publish).times(2) + events = [] + ActiveSupport::Notifications.subscribe { |*args| events << args } buffer = 'generated till now -> ' @controller.fragment_for(buffer, 'expensive') { fragment_computed = true } assert fragment_computed assert_equal 'generated till now -> ', buffer + assert_equal [:fragment_exist?, :write_fragment], events.map(&:first) end end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 496445fc34..b8bcdc2808 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -251,9 +251,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest get '/projects/1/companies/1/people' assert_equal 'people#index', @response.body - pending do - assert_equal '/projects/1/companies/1/people', project_company_people_path(:project_id => '1', :company_id => '1') - end + assert_equal '/projects/1/companies/1/people', project_company_people_path(:project_id => '1', :company_id => '1') get '/projects/1/companies/1/avatar' assert_equal 'avatars#show', @response.body @@ -345,9 +343,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest get '/projects/1/posts/1/comments' assert_equal 'comments#index', @response.body - pending do - assert_equal '/projects/1/posts/1/comments', project_post_comments_path(:project_id => '1', :post_id => '1') - end + assert_equal '/projects/1/posts/1/comments', project_post_comments_path(:project_id => '1', :post_id => '1') post '/projects/1/posts/1/comments/preview' assert_equal 'comments#preview', @response.body |