diff options
112 files changed, 1065 insertions, 781 deletions
diff --git a/actionmailer/test/i18n_with_controller_test.rb b/actionmailer/test/i18n_with_controller_test.rb index 7040ae6f8d..68ed86e0d4 100644 --- a/actionmailer/test/i18n_with_controller_test.rb +++ b/actionmailer/test/i18n_with_controller_test.rb @@ -24,7 +24,7 @@ end class ActionMailerI18nWithControllerTest < ActionDispatch::IntegrationTest Routes = ActionDispatch::Routing::RouteSet.new Routes.draw do - match ':controller(/:action(/:id))' + get ':controller(/:action(/:id))' end def app diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb index 0536e83098..2ea1723434 100644 --- a/actionmailer/test/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -57,8 +57,8 @@ class ActionMailerUrlTest < ActionMailer::TestCase UrlTestMailer.delivery_method = :test AppRoutes.draw do - match ':controller(/:action(/:id))' - match '/welcome' => "foo#bar", :as => "welcome" + get ':controller(/:action(/:id))' + get '/welcome' => "foo#bar", :as => "welcome" end expected = new_mail diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index aaa2223d9e..4266ec042e 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -23,7 +23,6 @@ module ActionDispatch end def url_for(options = {}) - path = "" path << options.delete(:script_name).to_s.chomp("/") path << options.delete(:path).to_s diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index d924f21fad..ec15a2a715 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -5,11 +5,14 @@ module ActionDispatch # IP addresses that are "trusted proxies" that can be stripped from # the comma-delimited list in the X-Forwarded-For header. See also: # http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces + # http://en.wikipedia.org/wiki/Private_network#Private_IPv6_addresses. TRUSTED_PROXIES = %r{ ^127\.0\.0\.1$ | # localhost + ^::1$ | ^(10 | # private IP 10.x.x.x 172\.(1[6-9]|2[0-9]|3[0-1]) | # private IP in the range 172.16.0.0 .. 172.31.255.255 - 192\.168 # private IP 192.168.x.x + 192\.168 | # private IP 192.168.x.x + fc00:: # private IP fc00 )\. }x @@ -19,13 +22,13 @@ module ActionDispatch @app = app @check_ip = check_ip_spoofing @proxies = case custom_proxies - when Regexp - custom_proxies - when nil - TRUSTED_PROXIES - else - Regexp.union(TRUSTED_PROXIES, custom_proxies) - end + when Regexp + custom_proxies + when nil + TRUSTED_PROXIES + else + Regexp.union(TRUSTED_PROXIES, custom_proxies) + end end def call(env) @@ -34,6 +37,31 @@ module ActionDispatch end class GetIp + + # IP v4 and v6 (with compression) validation regexp + # https://gist.github.com/1289635 + VALID_IP = %r{ + (^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}$) | # ip v4 + (^( + (([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}) | # ip v6 not abbreviated + (([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4}) | # ip v6 with double colon in the end + (([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4}) | # - ip addresses v6 + (([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4}) | # - with + (([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4}) | # - double colon + (([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4}) | # - in the middle + (([0-9A-Fa-f]{1,4}:){6} ((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3} (\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + (([0-9A-Fa-f]{1,4}:){1,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + (([0-9A-Fa-f]{1,4}:){1}:([0-9A-Fa-f]{1,4}:){0,4}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + (([0-9A-Fa-f]{1,4}:){0,2}:([0-9A-Fa-f]{1,4}:){0,3}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + (([0-9A-Fa-f]{1,4}:){0,3}:([0-9A-Fa-f]{1,4}:){0,2}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + (([0-9A-Fa-f]{1,4}:){0,4}:([0-9A-Fa-f]{1,4}:){1}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + (::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d) |(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)) | # ip v6 with compatible to v4 + ([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4}) | # ip v6 with compatible to v4 + (::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4}) | # ip v6 with double colon at the begining + (([0-9A-Fa-f]{1,4}:){1,7}:) # ip v6 without ending + )$) + }x + def initialize(env, middleware) @env = env @middleware = middleware @@ -44,25 +72,31 @@ module ActionDispatch # but will be wrong if the user is behind a proxy. Proxies will set # HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR, so we prioritize those. # HTTP_X_FORWARDED_FOR may be a comma-delimited list in the case of - # multiple chained proxies. The last address which is not a known proxy - # will be the originating IP. + # multiple chained proxies. The first address which is in this list + # if it's not a known proxy will be the originating IP. + # Format of HTTP_X_FORWARDED_FOR: + # client_ip, proxy_ip1, proxy_ip2... + # http://en.wikipedia.org/wiki/X-Forwarded-For def calculate_ip - client_ip = @env['HTTP_CLIENT_IP'] - forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR') - remote_addrs = ips_from('REMOTE_ADDR') + client_ip = @env['HTTP_CLIENT_IP'] + forwarded_ip = ips_from('HTTP_X_FORWARDED_FOR').first + remote_addrs = ips_from('REMOTE_ADDR') check_ip = client_ip && @middleware.check_ip - if check_ip && !forwarded_ips.include?(client_ip) + if check_ip && forwarded_ip != client_ip # We don't know which came from the proxy, and which from the user raise IpSpoofAttackError, "IP spoofing attack?!" \ "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \ "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" end - not_proxy = client_ip || forwarded_ips.first || remote_addrs.first - - # Return first REMOTE_ADDR if there are no other options - not_proxy || ips_from('REMOTE_ADDR', :allow_proxies).first + client_ips = remove_proxies [client_ip, forwarded_ip, remote_addrs].flatten + if client_ips.present? + client_ips.first + else + # If there is no client ip we can return first valid proxy ip from REMOTE_ADDR + remote_addrs.find { |ip| valid_ip? ip } + end end def to_s @@ -71,12 +105,24 @@ module ActionDispatch @ip = calculate_ip end - protected + private - def ips_from(header, allow_proxies = false) - ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : [] - allow_proxies ? ips : ips.reject{|ip| ip =~ @middleware.proxies } + def ips_from(header) + @env[header] ? @env[header].strip.split(/[,\s]+/) : [] end + + def valid_ip?(ip) + ip =~ VALID_IP + end + + def not_a_proxy?(ip) + ip !~ @middleware.proxies + end + + def remove_proxies(ips) + ips.select { |ip| valid_ip?(ip) && not_a_proxy?(ip) } + end + end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 910dc8ed6c..fdc0bfb686 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -59,6 +59,16 @@ module ActionDispatch @options = (@scope[:options] || {}).merge(options) @path = normalize_path(path) normalize_options! + + via_all = @options.delete(:via) if @options[:via] == :all + + if !via_all && request_method_condition.empty? + msg = "You should not use the `match` method in your router without specifying an HTTP method.\n" \ + "If you want to expose your action to GET, use `get` in the router:\n\n" \ + " Instead of: match \"controller#action\"\n" \ + " Do: get \"controller#action\"" + raise msg + end end def to_route @@ -264,7 +274,7 @@ module ActionDispatch # of most Rails applications, this is beneficial. def root(options = {}) options = { :to => options } if options.is_a?(String) - match '/', { :as => :root }.merge(options) + match '/', { :as => :root, :via => :get }.merge(options) end # Matches a url pattern to one or more routes. Any symbols in a pattern @@ -417,7 +427,7 @@ module ActionDispatch options[:as] ||= app_name(app) - match(path, options.merge(:to => app, :anchor => false, :format => false)) + match(path, options.merge(:to => app, :anchor => false, :format => false, :via => :all)) define_generate_prefix(app, options[:as]) self diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index ffb1afa089..81f856feda 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -64,6 +64,9 @@ module ActionView # distance_of_time_in_words(to_time, from_time, true) # => about 6 years # distance_of_time_in_words(Time.now, Time.now) # => less than a minute # + # distance_of_time_in_words(70) # => 1 minute + # distance_of_time_in_words(60*60) # => about 1 hour + # def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {}) from_time = from_time.to_time if from_time.respond_to?(:to_time) to_time = to_time.to_time if to_time.respond_to?(:to_time) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ad097f2eb7..8e7224937d 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -902,7 +902,7 @@ module ActionView # # Let's say that @post.validated? is 1: # check_box("post", "validated") # # => <input name="post[validated]" type="hidden" value="0" /> - # # <input type="checkbox" id="post_validated" name="post[validated]" value="1" /> + # # <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" /> # # # Let's say that @puppy.gooddog is "no": # check_box("puppy", "gooddog", {}, "yes", "no") diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index b1a5356ddd..22ba047328 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -125,11 +125,11 @@ module ActiveSupport # have been loaded. setup_once do SharedTestRoutes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end ActionDispatch::IntegrationTest.app.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end end end diff --git a/actionpack/test/activerecord/active_record_store_test.rb b/actionpack/test/activerecord/active_record_store_test.rb index 2fe7959f5a..fceebe1858 100644 --- a/actionpack/test/activerecord/active_record_store_test.rb +++ b/actionpack/test/activerecord/active_record_store_test.rb @@ -259,7 +259,7 @@ class ActiveRecordStoreTest < ActionDispatch::IntegrationTest def with_test_route_set(options = {}) with_routing do |set| set.draw do - match ':action', :to => 'active_record_store_test/test' + get ':action', :to => 'active_record_store_test/test' end @app = self.class.build_app(set) do |middleware| diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 01cafe1aca..b121ca9481 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -162,7 +162,7 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase def test_string_constraint with_routing do |set| set.draw do - match "photos", :to => 'action_pack_assertions#nothing', :constraints => {:subdomain => "admin"} + get "photos", :to => 'action_pack_assertions#nothing', :constraints => {:subdomain => "admin"} end end end @@ -170,9 +170,9 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase def test_assert_redirect_to_named_route_failure with_routing do |set| set.draw do - match 'route_one', :to => 'action_pack_assertions#nothing', :as => :route_one - match 'route_two', :to => 'action_pack_assertions#nothing', :id => 'two', :as => :route_two - match ':controller/:action' + get 'route_one', :to => 'action_pack_assertions#nothing', :as => :route_one + get 'route_two', :to => 'action_pack_assertions#nothing', :id => 'two', :as => :route_two + get ':controller/:action' end process :redirect_to_named_route assert_raise(ActiveSupport::TestCase::Assertion) do @@ -192,8 +192,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase with_routing do |set| set.draw do - match 'admin/inner_module', :to => 'admin/inner_module#index', :as => :admin_inner_module - match ':controller/:action' + get 'admin/inner_module', :to => 'admin/inner_module#index', :as => :admin_inner_module + get ':controller/:action' end process :redirect_to_index # redirection is <{"action"=>"index", "controller"=>"admin/admin/inner_module"}> @@ -206,8 +206,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase with_routing do |set| set.draw do - match '/action_pack_assertions/:id', :to => 'action_pack_assertions#index', :as => :top_level - match ':controller/:action' + get '/action_pack_assertions/:id', :to => 'action_pack_assertions#index', :as => :top_level + get ':controller/:action' end process :redirect_to_top_level_named_route # assert_redirected_to "http://test.host/action_pack_assertions/foo" would pass because of exact match early return @@ -221,8 +221,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase with_routing do |set| set.draw do # this controller exists in the admin namespace as well which is the only difference from previous test - match '/user/:id', :to => 'user#index', :as => :top_level - match ':controller/:action' + get '/user/:id', :to => 'user#index', :as => :top_level + get ':controller/:action' end process :redirect_to_top_level_named_route # assert_redirected_to top_level_url('foo') would pass because of exact match early return diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 2032aca52e..b9513ccff4 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -158,7 +158,7 @@ class UrlOptionsTest < ActionController::TestCase def test_url_for_query_params_included rs = ActionDispatch::Routing::RouteSet.new rs.draw do - match 'home' => 'pages#home' + get 'home' => 'pages#home' end options = { @@ -174,8 +174,8 @@ class UrlOptionsTest < ActionController::TestCase def test_url_options_override with_routing do |set| set.draw do - match 'from_view', :to => 'url_options#from_view', :as => :from_view - match ':controller/:action' + get 'from_view', :to => 'url_options#from_view', :as => :from_view + get ':controller/:action' end get :from_view, :route => "from_view_url" @@ -189,7 +189,7 @@ class UrlOptionsTest < ActionController::TestCase def test_url_helpers_does_not_become_actions with_routing do |set| set.draw do - match "account/overview" + get "account/overview" end assert !@controller.class.action_methods.include?("account_overview_path") @@ -208,8 +208,8 @@ class DefaultUrlOptionsTest < ActionController::TestCase def test_default_url_options_override with_routing do |set| set.draw do - match 'from_view', :to => 'default_url_options#from_view', :as => :from_view - match ':controller/:action' + get 'from_view', :to => 'default_url_options#from_view', :as => :from_view + get ':controller/:action' end get :from_view, :route => "from_view_url" @@ -226,7 +226,7 @@ class DefaultUrlOptionsTest < ActionController::TestCase scope("/:locale") do resources :descriptions end - match ':controller/:action' + get ':controller/:action' end get :from_view, :route => "description_path(1)" diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index a42c68a628..e8546cb154 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -102,8 +102,8 @@ class PageCachingTest < ActionController::TestCase def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route with_routing do |set| set.draw do - match 'posts.:format', :to => 'posts#index', :as => :formatted_posts - match '/', :to => 'posts#index', :as => :main + get 'posts.:format', :to => 'posts#index', :as => :formatted_posts + get '/', :to => 'posts#index', :as => :main end @params[:format] = 'rss' assert_equal '/posts.rss', @routes.url_for(@params) @@ -560,7 +560,7 @@ class ActionCacheTest < ActionController::TestCase def test_xml_version_of_resource_is_treated_as_different_cache with_routing do |set| set.draw do - match ':controller(/:action(.:format))' + get ':controller(/:action(.:format))' end get :index, :format => 'xml' diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index 37ccc7a4a5..e4b34125ad 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -277,7 +277,7 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest def with_test_route_set with_routing do |set| set.draw do - match ':action', :to => FlashIntegrationTest::TestController + get ':action', :to => FlashIntegrationTest::TestController end @app = self.class.build_app(set) do |middleware| diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 44f033119d..877b91b563 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -466,7 +466,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end set.draw do - match ':action', :to => controller + match ':action', :to => controller, :via => [:get, :post] get 'get/:action', :to => controller end @@ -530,10 +530,10 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest end routes.draw do - match '', :to => 'application_integration_test/test#index', :as => :empty_string + get '', :to => 'application_integration_test/test#index', :as => :empty_string - match 'foo', :to => 'application_integration_test/test#index', :as => :foo - match 'bar', :to => 'application_integration_test/test#index', :as => :bar + get 'foo', :to => 'application_integration_test/test#index', :as => :foo + get 'bar', :to => 'application_integration_test/test#index', :as => :bar end def app diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 0e4099ddc6..ac056319fc 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -1118,7 +1118,7 @@ class RespondWithControllerTest < ActionController::TestCase resources :quiz_stores do resources :customers end - match ":controller/:action" + get ":controller/:action" end yield end diff --git a/actionpack/test/controller/new_base/content_type_test.rb b/actionpack/test/controller/new_base/content_type_test.rb index 4b70031c90..9b57641e75 100644 --- a/actionpack/test/controller/new_base/content_type_test.rb +++ b/actionpack/test/controller/new_base/content_type_test.rb @@ -43,7 +43,7 @@ module ContentType test "default response is HTML and UTF8" do with_routing do |set| set.draw do - match ':controller', :action => 'index' + get ':controller', :action => 'index' end get "/content_type/base" diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb index ade204c387..00c7df2af8 100644 --- a/actionpack/test/controller/new_base/render_template_test.rb +++ b/actionpack/test/controller/new_base/render_template_test.rb @@ -164,7 +164,7 @@ module RenderTemplate test "rendering with implicit layout" do with_routing do |set| - set.draw { match ':controller', :action => :index } + set.draw { get ':controller', :action => :index } get "/render_template/with_layout" diff --git a/actionpack/test/controller/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb index 60468bf5c7..cc7f12ac6d 100644 --- a/actionpack/test/controller/new_base/render_test.rb +++ b/actionpack/test/controller/new_base/render_test.rb @@ -57,7 +57,7 @@ module Render test "render with blank" do with_routing do |set| set.draw do - match ":controller", :action => 'index' + get ":controller", :action => 'index' end get "/render/blank_render" @@ -70,7 +70,7 @@ module Render test "rendering more than once raises an exception" do with_routing do |set| set.draw do - match ":controller", :action => 'index' + get ":controller", :action => 'index' end assert_raises(AbstractController::DoubleRenderError) do diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb index 06d500cca7..e0b38b29fa 100644 --- a/actionpack/test/controller/new_base/render_text_test.rb +++ b/actionpack/test/controller/new_base/render_text_test.rb @@ -67,7 +67,7 @@ module RenderText test "rendering text from a action with default options renders the text with the layout" do with_routing do |set| - set.draw { match ':controller', :action => 'index' } + set.draw { get ':controller', :action => 'index' } get "/render_text/simple" assert_body "hello david" @@ -77,7 +77,7 @@ module RenderText test "rendering text from a action with default options renders the text without the layout" do with_routing do |set| - set.draw { match ':controller', :action => 'index' } + set.draw { get ':controller', :action => 'index' } get "/render_text/with_layout" diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index 6dab42d75d..4331333b98 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -262,7 +262,7 @@ class RedirectTest < ActionController::TestCase with_routing do |set| set.draw do resources :workshops - match ':controller/:action' + get ':controller/:action' end get :redirect_to_existing_record @@ -296,7 +296,7 @@ class RedirectTest < ActionController::TestCase def test_redirect_to_with_block_and_accepted_options with_routing do |set| set.draw do - match ':controller/:action' + get ':controller/:action' end get :redirect_to_with_block_and_options diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index fce13d096c..10f62dad65 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1188,7 +1188,7 @@ class RenderTest < ActionController::TestCase with_routing do |set| set.draw do resources :customers - match ':controller/:action' + get ':controller/:action' end get :head_with_location_object diff --git a/actionpack/test/controller/render_xml_test.rb b/actionpack/test/controller/render_xml_test.rb index 8b4f2f5349..4f280c4bec 100644 --- a/actionpack/test/controller/render_xml_test.rb +++ b/actionpack/test/controller/render_xml_test.rb @@ -72,7 +72,7 @@ class RenderXmlTest < ActionController::TestCase with_routing do |set| set.draw do resources :customers - match ':controller/:action' + get ':controller/:action' end get :render_with_object_location diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index 76c3dfe0d4..48e2d6491e 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -338,9 +338,9 @@ class RescueTest < ActionDispatch::IntegrationTest def with_test_routing with_routing do |set| set.draw do - match 'foo', :to => ::RescueTest::TestController.action(:foo) - match 'invalid', :to => ::RescueTest::TestController.action(:invalid) - match 'b00m', :to => ::RescueTest::TestController.action(:b00m) + get 'foo', :to => ::RescueTest::TestController.action(:foo) + get 'invalid', :to => ::RescueTest::TestController.action(:invalid) + get 'b00m', :to => ::RescueTest::TestController.action(:b00m) end yield end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 3c0a5d36ca..9fc875014c 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -680,7 +680,7 @@ class ResourcesTest < ActionController::TestCase scope '/threads/:thread_id' do resources :messages, :as => 'thread_messages' do get :search, :on => :collection - match :preview, :on => :new + get :preview, :on => :new end end end @@ -698,7 +698,7 @@ class ResourcesTest < ActionController::TestCase scope '/admin' do resource :account, :as => :admin_account do get :login, :on => :member - match :preview, :on => :new + get :preview, :on => :new end end end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 272a7da8c5..9441b46d47 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -17,7 +17,7 @@ class UriReservedCharactersRoutingTest < ActiveSupport::TestCase def setup @set = ActionDispatch::Routing::RouteSet.new @set.draw do - match ':controller/:action/:variable/*additional' + get ':controller/:action/:variable/*additional' end safe, unsafe = %w(: @ & = + $ , ;), %w(^ ? # [ ]) @@ -85,7 +85,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_symbols_with_dashes rs.draw do - match '/:artist/:song-omg', :to => lambda { |env| + get '/:artist/:song-omg', :to => lambda { |env| resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] [200, {}, [resp]] } @@ -97,7 +97,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_id_with_dash rs.draw do - match '/journey/:id', :to => lambda { |env| + get '/journey/:id', :to => lambda { |env| resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] [200, {}, [resp]] } @@ -109,7 +109,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_dash_with_custom_regexp rs.draw do - match '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env| + get '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env| resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] [200, {}, [resp]] } @@ -122,7 +122,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_pre_dash rs.draw do - match '/:artist/omg-:song', :to => lambda { |env| + get '/:artist/omg-:song', :to => lambda { |env| resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] [200, {}, [resp]] } @@ -134,7 +134,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_pre_dash_with_custom_regexp rs.draw do - match '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env| + get '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env| resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] [200, {}, [resp]] } @@ -147,7 +147,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_star_paths_are_greedy rs.draw do - match "/*path", :to => lambda { |env| + get "/*path", :to => lambda { |env| x = env["action_dispatch.request.path_parameters"][:path] [200, {}, [x]] }, :format => false @@ -159,7 +159,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_star_paths_are_greedy_but_not_too_much rs.draw do - match "/*path", :to => lambda { |env| + get "/*path", :to => lambda { |env| x = JSON.dump env["action_dispatch.request.path_parameters"] [200, {}, [x]] } @@ -172,7 +172,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_optional_star_paths_are_greedy rs.draw do - match "/(*filters)", :to => lambda { |env| + get "/(*filters)", :to => lambda { |env| x = env["action_dispatch.request.path_parameters"][:filters] [200, {}, [x]] }, :format => false @@ -184,7 +184,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_optional_star_paths_are_greedy_but_not_too_much rs.draw do - match "/(*filters)", :to => lambda { |env| + get "/(*filters)", :to => lambda { |env| x = JSON.dump env["action_dispatch.request.path_parameters"] [200, {}, [x]] } @@ -198,11 +198,11 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_regexp_precidence @rs.draw do - match '/whois/:domain', :constraints => { + get '/whois/:domain', :constraints => { :domain => /\w+\.[\w\.]+/ }, :to => lambda { |env| [200, {}, %w{regexp}] } - match '/whois/:id', :to => lambda { |env| [200, {}, %w{id}] } + get '/whois/:id', :to => lambda { |env| [200, {}, %w{id}] } end assert_equal 'regexp', get(URI('http://example.org/whois/example.org')) @@ -217,9 +217,9 @@ class LegacyRouteSetTests < ActiveSupport::TestCase } @rs.draw do - match '/', :constraints => subdomain.new, + get '/', :constraints => subdomain.new, :to => lambda { |env| [200, {}, %w{default}] } - match '/', :constraints => { :subdomain => 'clients' }, + get '/', :constraints => { :subdomain => 'clients' }, :to => lambda { |env| [200, {}, %w{clients}] } end @@ -229,11 +229,11 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_lambda_constraints @rs.draw do - match '/', :constraints => lambda { |req| + get '/', :constraints => lambda { |req| req.subdomain.present? and req.subdomain != "clients" }, :to => lambda { |env| [200, {}, %w{default}] } - match '/', :constraints => lambda { |req| + get '/', :constraints => lambda { |req| req.subdomain.present? && req.subdomain == "clients" }, :to => lambda { |env| [200, {}, %w{clients}] } end @@ -271,7 +271,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end def test_default_setup - @rs.draw { match '/:controller(/:action(/:id))' } + @rs.draw { get '/:controller(/:action(/:id))' } assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content")) assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list")) assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10")) @@ -289,21 +289,21 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_ignores_leading_slash @rs.clear! - @rs.draw { match '/:controller(/:action(/:id))'} + @rs.draw { get '/:controller(/:action(/:id))'} test_default_setup end def test_route_with_colon_first rs.draw do - match '/:controller/:action/:id', :action => 'index', :id => nil - match ':url', :controller => 'tiny_url', :action => 'translate' + get '/:controller/:action/:id', :action => 'index', :id => nil + get ':url', :controller => 'tiny_url', :action => 'translate' end end def test_route_with_regexp_for_controller rs.draw do - match ':controller/:admintoken(/:action(/:id))', :controller => /admin\/.+/ - match '/:controller(/:action(/:id))' + get ':controller/:admintoken(/:action(/:id))', :controller => /admin\/.+/ + get '/:controller(/:action(/:id))' end assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"}, @@ -317,7 +317,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_route_with_regexp_and_captures_for_controller rs.draw do - match '/:controller(/:action(/:id))', :controller => /admin\/(accounts|users)/ + get '/:controller(/:action(/:id))', :controller => /admin\/(accounts|users)/ end assert_equal({:controller => "admin/accounts", :action => "index"}, rs.recognize_path("/admin/accounts")) assert_equal({:controller => "admin/users", :action => "index"}, rs.recognize_path("/admin/users")) @@ -326,7 +326,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_route_with_regexp_and_dot rs.draw do - match ':controller/:action/:file', + get ':controller/:action/:file', :controller => /admin|user/, :action => /upload|download/, :defaults => {:file => nil}, @@ -356,7 +356,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_with_option rs.draw do - match 'page/:title' => 'content#show_page', :as => 'page' + get 'page/:title' => 'content#show_page', :as => 'page' end assert_equal("http://test.host/page/new%20stuff", @@ -365,7 +365,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_with_default rs.draw do - match 'page/:title' => 'content#show_page', :title => 'AboutPage', :as => 'page' + get 'page/:title' => 'content#show_page', :title => 'AboutPage', :as => 'page' end assert_equal("http://test.host/page/AboutRails", @@ -375,7 +375,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_with_path_prefix rs.draw do scope "my" do - match 'page' => 'content#show_page', :as => 'page' + get 'page' => 'content#show_page', :as => 'page' end end @@ -386,7 +386,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_with_blank_path_prefix rs.draw do scope "" do - match 'page' => 'content#show_page', :as => 'page' + get 'page' => 'content#show_page', :as => 'page' end end @@ -396,7 +396,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_with_nested_controller rs.draw do - match 'admin/user' => 'admin/user#index', :as => "users" + get 'admin/user' => 'admin/user#index', :as => "users" end assert_equal("http://test.host/admin/user", @@ -405,7 +405,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_optimised_named_route_with_host rs.draw do - match 'page' => 'content#show_page', :as => 'pages', :host => 'foo.com' + get 'page' => 'content#show_page', :as => 'pages', :host => 'foo.com' end routes = setup_for_named_route routes.expects(:url_for).with({ @@ -424,7 +424,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_without_hash rs.draw do - match ':controller/:action/:id', :as => 'normal' + get ':controller/:action/:id', :as => 'normal' end end @@ -448,9 +448,9 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_with_regexps rs.draw do - match 'page/:year/:month/:day/:title' => 'page#show', :as => 'article', + get 'page/:year/:month/:day/:title' => 'page#show', :as => 'article', :year => /\d+/, :month => /\d+/, :day => /\d+/ - match ':controller/:action/:id' + get ':controller/:action/:id' end routes = setup_for_named_route @@ -460,7 +460,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end def test_changing_controller - @rs.draw { match ':controller/:action/:id' } + @rs.draw { get ':controller/:action/:id' } assert_equal '/admin/stuff/show/10', url_for(rs, {:controller => 'stuff', :action => 'show', :id => 10}, @@ -469,8 +469,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_paths_escaped rs.draw do - match 'file/*path' => 'content#show_file', :as => 'path' - match ':controller/:action/:id' + get 'file/*path' => 'content#show_file', :as => 'path' + get ':controller/:action/:id' end # No + to space in URI escaping, only for query params. @@ -486,7 +486,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_paths_slashes_unescaped_with_ordered_parameters rs.draw do - match '/file/*path' => 'content#index', :as => 'path' + get '/file/*path' => 'content#index', :as => 'path' end # No / to %2F in URI, only for query params. @@ -495,14 +495,14 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_non_controllers_cannot_be_matched rs.draw do - match ':controller/:action/:id' + get ':controller/:action/:id' end assert_raise(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") } end def test_should_list_options_diff_when_routing_constraints_dont_match rs.draw do - match 'post/:id' => 'post#show', :constraints => { :id => /\d+/ }, :as => 'post' + get 'post/:id' => 'post#show', :constraints => { :id => /\d+/ }, :as => 'post' end assert_raise(ActionController::RoutingError) do url_for(rs, { :controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post" }) @@ -511,7 +511,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_dynamic_path_allowed rs.draw do - match '*path' => 'content#show_file' + get '*path' => 'content#show_file' end assert_equal '/pages/boo', @@ -520,7 +520,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_dynamic_recall_paths_allowed rs.draw do - match '*path' => 'content#show_file' + get '*path' => 'content#show_file' end assert_equal '/pages/boo', @@ -529,8 +529,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_backwards rs.draw do - match 'page/:id(/:action)' => 'pages#show' - match ':controller(/:action(/:id))' + get 'page/:id(/:action)' => 'pages#show' + get ':controller(/:action(/:id))' end assert_equal '/page/20', url_for(rs, { :id => 20 }, { :controller => 'pages', :action => 'show' }) @@ -540,8 +540,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_route_with_fixnum_default rs.draw do - match 'page(/:id)' => 'content#show_page', :id => 1 - match ':controller/:action/:id' + get 'page(/:id)' => 'content#show_page', :id => 1 + get ':controller/:action/:id' end assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page' }) @@ -557,8 +557,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase # For newer revision def test_route_with_text_default rs.draw do - match 'page/:id' => 'content#show_page', :id => 1 - match ':controller/:action/:id' + get 'page/:id' => 'content#show_page', :id => 1 + get ':controller/:action/:id' end assert_equal '/page/foo', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 'foo' }) @@ -573,13 +573,13 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end def test_action_expiry - @rs.draw { match ':controller(/:action(/:id))' } + @rs.draw { get ':controller(/:action(/:id))' } assert_equal '/content', url_for(rs, { :controller => 'content' }, { :controller => 'content', :action => 'show' }) end def test_requirement_should_prevent_optional_id rs.draw do - match 'post/:id' => 'post#show', :constraints => {:id => /\d+/}, :as => 'post' + get 'post/:id' => 'post#show', :constraints => {:id => /\d+/}, :as => 'post' end assert_equal '/post/10', url_for(rs, { :controller => 'post', :action => 'show', :id => 10 }) @@ -591,11 +591,11 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_both_requirement_and_optional rs.draw do - match('test(/:year)' => 'post#show', :as => 'blog', + get('test(/:year)' => 'post#show', :as => 'blog', :defaults => { :year => nil }, :constraints => { :year => /\d{4}/ } ) - match ':controller/:action/:id' + get ':controller/:action/:id' end assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show' }) @@ -606,8 +606,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_set_to_nil_forgets rs.draw do - match 'pages(/:year(/:month(/:day)))' => 'content#list_pages', :month => nil, :day => nil - match ':controller/:action/:id' + get 'pages(/:year(/:month(/:day)))' => 'content#list_pages', :month => nil, :day => nil + get ':controller/:action/:id' end assert_equal '/pages/2005', @@ -649,8 +649,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_named_route_method rs.draw do - match 'categories' => 'content#categories', :as => 'categories' - match ':controller(/:action(/:id))' + get 'categories' => 'content#categories', :as => 'categories' + get ':controller(/:action(/:id))' end assert_equal '/categories', url_for(rs, { :controller => 'content', :action => 'categories' }) @@ -664,9 +664,9 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_nil_defaults rs.draw do - match 'journal' => 'content#list_journal', + get 'journal' => 'content#list_journal', :date => nil, :user_id => nil - match ':controller/:action/:id' + get ':controller/:action/:id' end assert_equal '/journal', url_for(rs, { @@ -698,7 +698,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_recognize_array_of_methods rs.draw do match '/match' => 'books#get_or_post', :via => [:get, :post] - match '/match' => 'books#not_get_or_post' + put '/match' => 'books#not_get_or_post' end params = rs.recognize_path("/match", :method => :post) @@ -710,10 +710,10 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_subpath_recognized rs.draw do - match '/books/:id/edit' => 'subpath_books#edit' - match '/items/:id/:action' => 'subpath_books' - match '/posts/new/:action' => 'subpath_books' - match '/posts/:id' => 'subpath_books#show' + get '/books/:id/edit' => 'subpath_books#edit' + get '/items/:id/:action' => 'subpath_books' + get '/posts/new/:action' => 'subpath_books' + get '/posts/:id' => 'subpath_books#show' end hash = rs.recognize_path "/books/17/edit" @@ -735,9 +735,9 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_subpath_generated rs.draw do - match '/books/:id/edit' => 'subpath_books#edit' - match '/items/:id/:action' => 'subpath_books' - match '/posts/new/:action' => 'subpath_books' + get '/books/:id/edit' => 'subpath_books#edit' + get '/items/:id/:action' => 'subpath_books' + get '/posts/new/:action' => 'subpath_books' end assert_equal "/books/7/edit", url_for(rs, { :controller => "subpath_books", :id => 7, :action => "edit" }) @@ -747,7 +747,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_failed_constraints_raises_exception_with_violated_constraints rs.draw do - match 'foos/:id' => 'foos#show', :as => 'foo_with_requirement', :constraints => { :id => /\d+/ } + get 'foos/:id' => 'foos#show', :as => 'foo_with_requirement', :constraints => { :id => /\d+/ } end assert_raise(ActionController::RoutingError) do @@ -758,11 +758,11 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_routes_changed_correctly_after_clear rs = ::ActionDispatch::Routing::RouteSet.new rs.draw do - match 'ca' => 'ca#aa' - match 'cb' => 'cb#ab' - match 'cc' => 'cc#ac' - match ':controller/:action/:id' - match ':controller/:action/:id.:format' + get 'ca' => 'ca#aa' + get 'cb' => 'cb#ab' + get 'cc' => 'cc#ac' + get ':controller/:action/:id' + get ':controller/:action/:id.:format' end hash = rs.recognize_path "/cc" @@ -771,10 +771,10 @@ class LegacyRouteSetTests < ActiveSupport::TestCase assert_equal %w(cc ac), [hash[:controller], hash[:action]] rs.draw do - match 'cb' => 'cb#ab' - match 'cc' => 'cc#ac' - match ':controller/:action/:id' - match ':controller/:action/:id.:format' + get 'cb' => 'cb#ab' + get 'cc' => 'cc#ac' + get ':controller/:action/:id' + get ':controller/:action/:id.:format' end hash = rs.recognize_path "/cc" @@ -799,29 +799,29 @@ class RouteSetTest < ActiveSupport::TestCase @default_route_set ||= begin set = ROUTING::RouteSet.new set.draw do - match '/:controller(/:action(/:id))' + get '/:controller(/:action(/:id))' end set end end def test_generate_extras - set.draw { match ':controller/(:action(/:id))' } + set.draw { get ':controller/(:action(/:id))' } path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") assert_equal "/foo/bar/15", path assert_equal %w(that this), extras.map { |e| e.to_s }.sort end def test_extra_keys - set.draw { match ':controller/:action/:id' } + set.draw { get ':controller/:action/:id' } extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") assert_equal %w(that this), extras.map { |e| e.to_s }.sort end def test_generate_extras_not_first set.draw do - match ':controller/:action/:id.:format' - match ':controller/:action/:id' + get ':controller/:action/:id.:format' + get ':controller/:action/:id' end path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") assert_equal "/foo/bar/15", path @@ -830,8 +830,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_generate_not_first set.draw do - match ':controller/:action/:id.:format' - match ':controller/:action/:id' + get ':controller/:action/:id.:format' + get ':controller/:action/:id' end assert_equal "/foo/bar/15?this=hello", url_for(set, { :controller => "foo", :action => "bar", :id => 15, :this => "hello" }) @@ -839,8 +839,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_extra_keys_not_first set.draw do - match ':controller/:action/:id.:format' - match ':controller/:action/:id' + get ':controller/:action/:id.:format' + get ':controller/:action/:id' end extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") assert_equal %w(that this), extras.map { |e| e.to_s }.sort @@ -849,7 +849,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_draw assert_equal 0, set.routes.size set.draw do - match '/hello/world' => 'a#b' + get '/hello/world' => 'a#b' end assert_equal 1, set.routes.size end @@ -857,7 +857,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_draw_symbol_controller_name assert_equal 0, set.routes.size set.draw do - match '/users/index' => 'users#index' + get '/users/index' => 'users#index' end set.recognize_path('/users/index', :method => :get) assert_equal 1, set.routes.size @@ -866,7 +866,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_named_draw assert_equal 0, set.routes.size set.draw do - match '/hello/world' => 'a#b', :as => 'hello' + get '/hello/world' => 'a#b', :as => 'hello' end assert_equal 1, set.routes.size assert_equal set.routes.first, set.named_routes[:hello] @@ -874,18 +874,18 @@ class RouteSetTest < ActiveSupport::TestCase def test_earlier_named_routes_take_precedence set.draw do - match '/hello/world' => 'a#b', :as => 'hello' - match '/hello' => 'a#b', :as => 'hello' + get '/hello/world' => 'a#b', :as => 'hello' + get '/hello' => 'a#b', :as => 'hello' end assert_equal set.routes.first, set.named_routes[:hello] end def setup_named_route_test set.draw do - match '/people(/:id)' => 'people#show', :as => 'show' - match '/people' => 'people#index', :as => 'index' - match '/people/go/:foo/:bar/joe(/:id)' => 'people#multi', :as => 'multi' - match '/admin/users' => 'admin/users#index', :as => "users" + get '/people(/:id)' => 'people#show', :as => 'show' + get '/people' => 'people#index', :as => 'index' + get '/people/go/:foo/:bar/joe(/:id)' => 'people#multi', :as => 'multi' + get '/admin/users' => 'admin/users#index', :as => "users" end MockController.build(set.url_helpers).new @@ -985,7 +985,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_draw_default_route set.draw do - match '/:controller/:action/:id' + get '/:controller/:action/:id' end assert_equal 1, set.routes.size @@ -999,8 +999,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_with_parameter_shell set.draw do - match 'page/:id' => 'pages#show', :id => /\d+/ - match '/:controller(/:action(/:id))' + get 'page/:id' => 'pages#show', :id => /\d+/ + get '/:controller(/:action(/:id))' end assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages')) @@ -1014,7 +1014,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_constraints_on_request_object_with_anchors_are_valid assert_nothing_raised do set.draw do - match 'page/:id' => 'pages#show', :constraints => { :host => /^foo$/ } + get 'page/:id' => 'pages#show', :constraints => { :host => /^foo$/ } end end end @@ -1022,27 +1022,27 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_constraints_with_anchor_chars_are_invalid assert_raise ArgumentError do set.draw do - match 'page/:id' => 'pages#show', :id => /^\d+/ + get 'page/:id' => 'pages#show', :id => /^\d+/ end end assert_raise ArgumentError do set.draw do - match 'page/:id' => 'pages#show', :id => /\A\d+/ + get 'page/:id' => 'pages#show', :id => /\A\d+/ end end assert_raise ArgumentError do set.draw do - match 'page/:id' => 'pages#show', :id => /\d+$/ + get 'page/:id' => 'pages#show', :id => /\d+$/ end end assert_raise ArgumentError do set.draw do - match 'page/:id' => 'pages#show', :id => /\d+\Z/ + get 'page/:id' => 'pages#show', :id => /\d+\Z/ end end assert_raise ArgumentError do set.draw do - match 'page/:id' => 'pages#show', :id => /\d+\z/ + get 'page/:id' => 'pages#show', :id => /\d+\z/ end end end @@ -1057,7 +1057,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_recognize_with_encoded_id_and_regex set.draw do - match 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/ + get 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/ end assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) @@ -1128,7 +1128,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_typo_recognition set.draw do - match 'articles/:year/:month/:day/:title' => 'articles#permalink', + get 'articles/:year/:month/:day/:title' => 'articles#permalink', :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/ end @@ -1143,7 +1143,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_routing_traversal_does_not_load_extra_classes assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded" set.draw do - match '/profile' => 'profile#index' + get '/profile' => 'profile#index' end set.recognize_path("/profile") rescue nil @@ -1177,8 +1177,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_generate_with_default_action set.draw do - match "/people", :controller => "people", :action => "index" - match "/people/list", :controller => "people", :action => "list" + get "/people", :controller => "people", :action => "index" + get "/people/list", :controller => "people", :action => "list" end url = url_for(set, { :controller => "people", :action => "list" }) @@ -1197,7 +1197,7 @@ class RouteSetTest < ActiveSupport::TestCase set.draw do namespace 'api' do - match 'inventory' => 'products#inventory' + get 'inventory' => 'products#inventory' end end @@ -1222,7 +1222,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_namespace_with_path_prefix set.draw do scope :module => "api", :path => "prefix" do - match 'inventory' => 'products#inventory' + get 'inventory' => 'products#inventory' end end @@ -1234,7 +1234,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_namespace_with_blank_path_prefix set.draw do scope :module => "api", :path => "" do - match 'inventory' => 'products#inventory' + get 'inventory' => 'products#inventory' end end @@ -1244,7 +1244,7 @@ class RouteSetTest < ActiveSupport::TestCase end def test_generate_changes_controller_module - set.draw { match ':controller/:action/:id' } + set.draw { get ':controller/:action/:id' } current = { :controller => "bling/bloop", :action => "bap", :id => 9 } assert_equal "/foo/bar/baz/7", @@ -1253,7 +1253,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_id_is_sticky_when_it_ought_to_be set.draw do - match ':controller/:id/:action' + get ':controller/:id/:action' end url = url_for(set, { :action => "destroy" }, { :controller => "people", :action => "show", :id => "7" }) @@ -1262,8 +1262,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_use_static_path_when_possible set.draw do - match 'about' => "welcome#about" - match ':controller/:action/:id' + get 'about' => "welcome#about" + get ':controller/:action/:id' end url = url_for(set, { :controller => "welcome", :action => "about" }, @@ -1273,7 +1273,7 @@ class RouteSetTest < ActiveSupport::TestCase end def test_generate - set.draw { match ':controller/:action/:id' } + set.draw { get ':controller/:action/:id' } args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" } assert_equal "/foo/bar/7?x=y", url_for(set, args) @@ -1284,7 +1284,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_generate_with_path_prefix set.draw do scope "my" do - match ':controller(/:action(/:id))' + get ':controller(/:action(/:id))' end end @@ -1295,7 +1295,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_generate_with_blank_path_prefix set.draw do scope "" do - match ':controller(/:action(/:id))' + get ':controller(/:action(/:id))' end end @@ -1305,9 +1305,9 @@ class RouteSetTest < ActiveSupport::TestCase def test_named_routes_are_never_relative_to_modules set.draw do - match "/connection/manage(/:action)" => 'connection/manage#index' - match "/connection/connection" => "connection/connection#index" - match '/connection' => 'connection#index', :as => 'family_connection' + get "/connection/manage(/:action)" => 'connection/manage#index' + get "/connection/connection" => "connection/connection#index" + get '/connection' => 'connection#index', :as => 'family_connection' end url = url_for(set, { :controller => "connection" }, { :controller => 'connection/manage' }) @@ -1319,7 +1319,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_action_left_off_when_id_is_recalled set.draw do - match ':controller(/:action(/:id))' + get ':controller(/:action(/:id))' end assert_equal '/books', url_for(set, {:controller => 'books', :action => 'index'}, @@ -1329,8 +1329,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_query_params_will_be_shown_when_recalled set.draw do - match 'show_weblog/:parameter' => 'weblog#show' - match ':controller(/:action(/:id))' + get 'show_weblog/:parameter' => 'weblog#show' + get ':controller(/:action(/:id))' end assert_equal '/weblog/edit?parameter=1', url_for(set, {:action => 'edit', :parameter => 1}, @@ -1340,7 +1340,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_format_is_not_inherit set.draw do - match '/posts(.:format)' => 'posts#index' + get '/posts(.:format)' => 'posts#index' end assert_equal '/posts', url_for(set, @@ -1355,7 +1355,7 @@ class RouteSetTest < ActiveSupport::TestCase end def test_expiry_determination_should_consider_values_with_to_param - set.draw { match 'projects/:project_id/:controller/:action' } + set.draw { get 'projects/:project_id/:controller/:action' } assert_equal '/projects/1/weblog/show', url_for(set, { :action => 'show', :project_id => 1 }, { :controller => 'weblog', :action => 'show', :project_id => '1' }) @@ -1365,7 +1365,7 @@ class RouteSetTest < ActiveSupport::TestCase set.draw do resources :projects do member do - match 'milestones' => 'milestones#index', :as => 'milestones' + get 'milestones' => 'milestones#index', :as => 'milestones' end end end @@ -1398,7 +1398,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_constraints_with_unsupported_regexp_options_must_error assert_raise ArgumentError do set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => { :name => /(david|jamis)/m } end end @@ -1407,13 +1407,13 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_constraints_with_supported_options_must_not_error assert_nothing_raised do set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => { :name => /(david|jamis)/i } end end assert_nothing_raised do set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => { :name => / # Desperately overcommented regexp ( #Either david #The Creator @@ -1427,7 +1427,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_with_subdomain_and_constraints_must_receive_params name_param = nil set.draw do - match 'page/:name' => 'pages#show', :constraints => lambda {|request| + get 'page/:name' => 'pages#show', :constraints => lambda {|request| name_param = request.params[:name] return true } @@ -1439,7 +1439,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_requirement_recognize_with_ignore_case set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => {:name => /(david|jamis)/i} end assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis')) @@ -1451,7 +1451,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_requirement_generate_with_ignore_case set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => {:name => /(david|jamis)/i} end @@ -1466,7 +1466,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_requirement_recognize_with_extended_syntax set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => {:name => / # Desperately overcommented regexp ( #Either david #The Creator @@ -1486,7 +1486,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_route_requirement_with_xi_modifiers set.draw do - match 'page/:name' => 'pages#show', + get 'page/:name' => 'pages#show', :constraints => {:name => / # Desperately overcommented regexp ( #Either david #The Creator @@ -1504,8 +1504,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_routes_with_symbols set.draw do - match 'unnamed', :controller => :pages, :action => :show, :name => :as_symbol - match 'named' , :controller => :pages, :action => :show, :name => :as_symbol, :as => :named + get 'unnamed', :controller => :pages, :action => :show, :name => :as_symbol + get 'named' , :controller => :pages, :action => :show, :name => :as_symbol, :as => :named end assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/unnamed')) assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named')) @@ -1513,8 +1513,8 @@ class RouteSetTest < ActiveSupport::TestCase def test_regexp_chunk_should_add_question_mark_for_optionals set.draw do - match '/' => 'foo#index' - match '/hello' => 'bar#index' + get '/' => 'foo#index' + get '/hello' => 'bar#index' end assert_equal '/', url_for(set, { :controller => 'foo' }) @@ -1526,7 +1526,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_assign_route_options_with_anchor_chars set.draw do - match '/cars/:action/:person/:car/', :controller => 'cars' + get '/cars/:action/:person/:car/', :controller => 'cars' end assert_equal '/cars/buy/1/2', url_for(set, { :controller => 'cars', :action => 'buy', :person => '1', :car => '2' }) @@ -1536,7 +1536,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_segmentation_of_dot_path set.draw do - match '/books/:action.rss', :controller => 'books' + get '/books/:action.rss', :controller => 'books' end assert_equal '/books/list.rss', url_for(set, { :controller => 'books', :action => 'list' }) @@ -1546,7 +1546,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_segmentation_of_dynamic_dot_path set.draw do - match '/books(/:action(.:format))', :controller => 'books' + get '/books(/:action(.:format))', :controller => 'books' end assert_equal '/books/list.rss', url_for(set, { :controller => 'books', :action => 'list', :format => 'rss' }) @@ -1562,7 +1562,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_slashes_are_implied @set = nil - set.draw { match("/:controller(/:action(/:id))") } + set.draw { get("/:controller(/:action(/:id))") } assert_equal '/content', url_for(set, { :controller => 'content', :action => 'index' }) assert_equal '/content/list', url_for(set, { :controller => 'content', :action => 'list' }) @@ -1647,13 +1647,13 @@ class RouteSetTest < ActiveSupport::TestCase def test_generate_with_default_params set.draw do - match 'dummy/page/:page' => 'dummy#show' - match 'dummy/dots/page.:page' => 'dummy#dots' - match 'ibocorp(/:page)' => 'ibocorp#show', + get 'dummy/page/:page' => 'dummy#show' + get 'dummy/dots/page.:page' => 'dummy#dots' + get 'ibocorp(/:page)' => 'ibocorp#show', :constraints => { :page => /\d+/ }, :defaults => { :page => 1 } - match ':controller/:action/:id' + get ':controller/:action/:id' end assert_equal '/ibocorp', url_for(set, { :controller => 'ibocorp', :action => "show", :page => 1 }) @@ -1661,17 +1661,17 @@ class RouteSetTest < ActiveSupport::TestCase def test_generate_with_optional_params_recalls_last_request set.draw do - match "blog/", :controller => "blog", :action => "index" + get "blog/", :controller => "blog", :action => "index" - match "blog(/:year(/:month(/:day)))", + get "blog(/:year(/:month(/:day)))", :controller => "blog", :action => "show_date", :constraints => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/ }, :day => nil, :month => nil - match "blog/show/:id", :controller => "blog", :action => "show", :id => /\d+/ - match "blog/:controller/:action(/:id)" - match "*anything", :controller => "blog", :action => "unknown_request" + get "blog/show/:id", :controller => "blog", :action => "show", :id => /\d+/ + get "blog/:controller/:action(/:id)" + get "*anything", :controller => "blog", :action => "unknown_request" end assert_equal({:controller => "blog", :action => "index"}, set.recognize_path("/blog")) @@ -1719,7 +1719,7 @@ class RackMountIntegrationTests < ActiveSupport::TestCase root :to => 'users#index' end - match '/blog(/:year(/:month(/:day)))' => 'posts#show_date', + get '/blog(/:year(/:month(/:day)))' => 'posts#show_date', :constraints => { :year => /(19|20)\d\d/, :month => /[01]?\d/, @@ -1728,37 +1728,37 @@ class RackMountIntegrationTests < ActiveSupport::TestCase :day => nil, :month => nil - match 'archive/:year', :controller => 'archive', :action => 'index', + get 'archive/:year', :controller => 'archive', :action => 'index', :defaults => { :year => nil }, :constraints => { :year => /\d{4}/ }, :as => "blog" resources :people - match 'legacy/people' => "people#index", :legacy => "true" + get 'legacy/people' => "people#index", :legacy => "true" - match 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol - match 'id_default(/:id)' => "foo#id_default", :id => 1 + get 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol + get 'id_default(/:id)' => "foo#id_default", :id => 1 match 'get_or_post' => "foo#get_or_post", :via => [:get, :post] - match 'optional/:optional' => "posts#index" - match 'projects/:project_id' => "project#index", :as => "project" - match 'clients' => "projects#index" + get 'optional/:optional' => "posts#index" + get 'projects/:project_id' => "project#index", :as => "project" + get 'clients' => "projects#index" - match 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i - match 'extended/geocode/:postalcode' => 'geocode#show',:constraints => { + get 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i + get 'extended/geocode/:postalcode' => 'geocode#show',:constraints => { :postalcode => /# Postcode format \d{5} #Prefix (-\d{4})? #Suffix /x }, :as => "geocode" - match 'news(.:format)' => "news#index" + get 'news(.:format)' => "news#index" - match 'comment/:id(/:action)' => "comments#show" - match 'ws/:controller(/:action(/:id))', :ws => true - match 'account(/:action)' => "account#subscription" - match 'pages/:page_id/:controller(/:action(/:id))' - match ':controller/ping', :action => 'ping' - match ':controller(/:action(/:id))(.:format)' + get 'comment/:id(/:action)' => "comments#show" + get 'ws/:controller(/:action(/:id))', :ws => true + get 'account(/:action)' => "account#subscription" + get 'pages/:page_id/:controller(/:action(/:id))' + get ':controller/ping', :action => 'ping' + match ':controller(/:action(/:id))(.:format)', :via => :all root :to => "news#index" } diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index ecba9fed22..e8411bae0c 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -138,7 +138,7 @@ XML @request.env['PATH_INFO'] = nil @routes = ActionDispatch::Routing::RouteSet.new.tap do |r| r.draw do - match ':controller(/:action(/:id))' + get ':controller(/:action(/:id))' end end end @@ -524,7 +524,7 @@ XML with_routing do |set| set.draw do namespace :admin do - match 'user' => 'user#index' + get 'user' => 'user#index' end end @@ -534,7 +534,7 @@ XML def test_assert_routing_with_glob with_routing do |set| - set.draw { match('*path' => "pages#show") } + set.draw { get('*path' => "pages#show") } assert_routing('/company/about', { :controller => 'pages', :action => 'show', :path => 'company/about' }) end end @@ -585,8 +585,8 @@ XML def test_array_path_parameter_handled_properly with_routing do |set| set.draw do - match 'file/*path', :to => 'test_case_test/test#test_params' - match ':controller/:action' + get 'file/*path', :to => 'test_case_test/test#test_params' + get ':controller/:action' end get :test_params, :path => ['hello', 'world'] diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb index 451ea6027d..6c2311e7a5 100644 --- a/actionpack/test/controller/url_for_integration_test.rb +++ b/actionpack/test/controller/url_for_integration_test.rb @@ -18,7 +18,7 @@ module ActionPack root :to => 'users#index' end - match '/blog(/:year(/:month(/:day)))' => 'posts#show_date', + get '/blog(/:year(/:month(/:day)))' => 'posts#show_date', :constraints => { :year => /(19|20)\d\d/, :month => /[01]?\d/, @@ -27,7 +27,7 @@ module ActionPack :day => nil, :month => nil - match 'archive/:year', :controller => 'archive', :action => 'index', + get 'archive/:year', :controller => 'archive', :action => 'index', :defaults => { :year => nil }, :constraints => { :year => /\d{4}/ }, :as => "blog" @@ -35,29 +35,29 @@ module ActionPack resources :people #match 'legacy/people' => "people#index", :legacy => "true" - match 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol - match 'id_default(/:id)' => "foo#id_default", :id => 1 + get 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol + get 'id_default(/:id)' => "foo#id_default", :id => 1 match 'get_or_post' => "foo#get_or_post", :via => [:get, :post] - match 'optional/:optional' => "posts#index" - match 'projects/:project_id' => "project#index", :as => "project" - match 'clients' => "projects#index" + get 'optional/:optional' => "posts#index" + get 'projects/:project_id' => "project#index", :as => "project" + get 'clients' => "projects#index" - match 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i - match 'extended/geocode/:postalcode' => 'geocode#show',:constraints => { + get 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i + get 'extended/geocode/:postalcode' => 'geocode#show',:constraints => { :postalcode => /# Postcode format \d{5} #Prefix (-\d{4})? #Suffix /x }, :as => "geocode" - match 'news(.:format)' => "news#index" + get 'news(.:format)' => "news#index" - match 'comment/:id(/:action)' => "comments#show" - match 'ws/:controller(/:action(/:id))', :ws => true - match 'account(/:action)' => "account#subscription" - match 'pages/:page_id/:controller(/:action(/:id))' - match ':controller/ping', :action => 'ping' - match ':controller(/:action(/:id))(.:format)' + get 'comment/:id(/:action)' => "comments#show" + get 'ws/:controller(/:action(/:id))', :ws => true + get 'account(/:action)' => "account#subscription" + get 'pages/:page_id/:controller(/:action(/:id))' + get ':controller/ping', :action => 'ping' + get ':controller(/:action(/:id))(.:format)' root :to => "news#index" } diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index aa233d6135..b2cb5f80d5 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -5,7 +5,7 @@ module AbstractController class UrlForTests < ActionController::TestCase class W - include ActionDispatch::Routing::RouteSet.new.tap { |r| r.draw { match ':controller(/:action(/:id(.:format)))' } }.url_helpers + include ActionDispatch::Routing::RouteSet.new.tap { |r| r.draw { get ':controller(/:action(/:id(.:format)))' } }.url_helpers end def teardown @@ -210,8 +210,8 @@ module AbstractController def test_named_routes with_routing do |set| set.draw do - match 'this/is/verbose', :to => 'home#index', :as => :no_args - match 'home/sweet/home/:user', :to => 'home#index', :as => :home + get 'this/is/verbose', :to => 'home#index', :as => :no_args + get 'home/sweet/home/:user', :to => 'home#index', :as => :home end # We need to create a new class in order to install the new named route. @@ -231,7 +231,7 @@ module AbstractController def test_relative_url_root_is_respected_for_named_routes with_routing do |set| set.draw do - match '/home/sweet/home/:user', :to => 'home#index', :as => :home + get '/home/sweet/home/:user', :to => 'home#index', :as => :home end kls = Class.new { include set.url_helpers } @@ -245,8 +245,8 @@ module AbstractController def test_only_path with_routing do |set| set.draw do - match 'home/sweet/home/:user', :to => 'home#index', :as => :home - match ':controller/:action/:id' + get 'home/sweet/home/:user', :to => 'home#index', :as => :home + get ':controller/:action/:id' end # We need to create a new class in order to install the new named route. @@ -313,8 +313,8 @@ module AbstractController def test_named_routes_with_nil_keys with_routing do |set| set.draw do - match 'posts.:format', :to => 'posts#index', :as => :posts - match '/', :to => 'posts#index', :as => :main + get 'posts.:format', :to => 'posts#index', :as => :posts + get '/', :to => 'posts#index', :as => :main end # We need to create a new class in order to install the new named route. diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index f88903b10e..cc3706aeee 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -21,7 +21,7 @@ class UrlRewriterTests < ActionController::TestCase @rewriter = Rewriter.new(@request) #.new(@request, @params) @routes = ActionDispatch::Routing::RouteSet.new.tap do |r| r.draw do - match ':controller(/:action(/:id))' + get ':controller(/:action(/:id))' end end end diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb index 351e61eeae..c0b9833603 100644 --- a/actionpack/test/controller/webservice_test.rb +++ b/actionpack/test/controller/webservice_test.rb @@ -254,7 +254,7 @@ class WebServiceTest < ActionDispatch::IntegrationTest def with_test_route_set with_routing do |set| set.draw do - match '/', :to => 'web_service_test/test#assign_parameters' + match '/', :to => 'web_service_test/test#assign_parameters', :via => :all end yield end diff --git a/actionpack/test/dispatch/mapper_test.rb b/actionpack/test/dispatch/mapper_test.rb index d3465589c1..8070bdec8a 100644 --- a/actionpack/test/dispatch/mapper_test.rb +++ b/actionpack/test/dispatch/mapper_test.rb @@ -37,7 +37,7 @@ module ActionDispatch end def test_mapping_requirements - options = { :controller => 'foo', :action => 'bar' } + options = { :controller => 'foo', :action => 'bar', :via => :get } m = Mapper::Mapping.new FakeSet.new, {}, '/store/:name(*rest)', options _, _, requirements, _ = m.to_route assert_equal(/.+?/, requirements[:rest]) @@ -46,7 +46,7 @@ module ActionDispatch def test_map_slash fakeset = FakeSet.new mapper = Mapper.new fakeset - mapper.match '/', :to => 'posts#index', :as => :main + mapper.get '/', :to => 'posts#index', :as => :main assert_equal '/', fakeset.conditions.first[:path_info] end @@ -55,14 +55,14 @@ module ActionDispatch mapper = Mapper.new fakeset # FIXME: is this a desired behavior? - mapper.match '/one/two/', :to => 'posts#index', :as => :main + mapper.get '/one/two/', :to => 'posts#index', :as => :main assert_equal '/one/two(.:format)', fakeset.conditions.first[:path_info] end def test_map_wildcard fakeset = FakeSet.new mapper = Mapper.new fakeset - mapper.match '/*path', :to => 'pages#show' + mapper.get '/*path', :to => 'pages#show' assert_equal '/*path(.:format)', fakeset.conditions.first[:path_info] assert_equal(/.+?/, fakeset.requirements.first[:path]) end @@ -70,7 +70,7 @@ module ActionDispatch def test_map_wildcard_with_other_element fakeset = FakeSet.new mapper = Mapper.new fakeset - mapper.match '/*path/foo/:bar', :to => 'pages#show' + mapper.get '/*path/foo/:bar', :to => 'pages#show' assert_equal '/*path/foo/:bar(.:format)', fakeset.conditions.first[:path_info] assert_nil fakeset.requirements.first[:path] end @@ -78,7 +78,7 @@ module ActionDispatch def test_map_wildcard_with_multiple_wildcard fakeset = FakeSet.new mapper = Mapper.new fakeset - mapper.match '/*foo/*bar', :to => 'pages#show' + mapper.get '/*foo/*bar', :to => 'pages#show' assert_equal '/*foo/*bar(.:format)', fakeset.conditions.first[:path_info] assert_nil fakeset.requirements.first[:foo] assert_equal(/.+?/, fakeset.requirements.first[:bar]) @@ -87,7 +87,7 @@ module ActionDispatch def test_map_wildcard_with_format_false fakeset = FakeSet.new mapper = Mapper.new fakeset - mapper.match '/*path', :to => 'pages#show', :format => false + mapper.get '/*path', :to => 'pages#show', :format => false assert_equal '/*path', fakeset.conditions.first[:path_info] assert_nil fakeset.requirements.first[:path] end @@ -95,7 +95,7 @@ module ActionDispatch def test_map_wildcard_with_format_true fakeset = FakeSet.new mapper = Mapper.new fakeset - mapper.match '/*path', :to => 'pages#show', :format => true + mapper.get '/*path', :to => 'pages#show', :format => true assert_equal '/*path.:format', fakeset.conditions.first[:path_info] end end diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb index bd5b5edab0..ab2f7612ce 100644 --- a/actionpack/test/dispatch/prefix_generation_test.rb +++ b/actionpack/test/dispatch/prefix_generation_test.rb @@ -25,12 +25,12 @@ module TestGenerationPrefix @routes ||= begin routes = ActionDispatch::Routing::RouteSet.new routes.draw do - match "/posts/:id", :to => "inside_engine_generating#show", :as => :post - match "/posts", :to => "inside_engine_generating#index", :as => :posts - match "/url_to_application", :to => "inside_engine_generating#url_to_application" - match "/polymorphic_path_for_engine", :to => "inside_engine_generating#polymorphic_path_for_engine" - match "/conflicting_url", :to => "inside_engine_generating#conflicting" - match "/foo", :to => "never#invoked", :as => :named_helper_that_should_be_invoked_only_in_respond_to_test + get "/posts/:id", :to => "inside_engine_generating#show", :as => :post + get "/posts", :to => "inside_engine_generating#index", :as => :posts + get "/url_to_application", :to => "inside_engine_generating#url_to_application" + get "/polymorphic_path_for_engine", :to => "inside_engine_generating#polymorphic_path_for_engine" + get "/conflicting_url", :to => "inside_engine_generating#conflicting" + get "/foo", :to => "never#invoked", :as => :named_helper_that_should_be_invoked_only_in_respond_to_test end routes @@ -51,12 +51,12 @@ module TestGenerationPrefix scope "/:omg", :omg => "awesome" do mount BlogEngine => "/blog", :as => "blog_engine" end - match "/posts/:id", :to => "outside_engine_generating#post", :as => :post - match "/generate", :to => "outside_engine_generating#index" - match "/polymorphic_path_for_app", :to => "outside_engine_generating#polymorphic_path_for_app" - match "/polymorphic_path_for_engine", :to => "outside_engine_generating#polymorphic_path_for_engine" - match "/polymorphic_with_url_for", :to => "outside_engine_generating#polymorphic_with_url_for" - match "/conflicting_url", :to => "outside_engine_generating#conflicting" + get "/posts/:id", :to => "outside_engine_generating#post", :as => :post + get "/generate", :to => "outside_engine_generating#index" + get "/polymorphic_path_for_app", :to => "outside_engine_generating#polymorphic_path_for_app" + get "/polymorphic_path_for_engine", :to => "outside_engine_generating#polymorphic_path_for_engine" + get "/polymorphic_with_url_for", :to => "outside_engine_generating#polymorphic_with_url_for" + get "/conflicting_url", :to => "outside_engine_generating#conflicting" root :to => "outside_engine_generating#index" end @@ -282,7 +282,7 @@ module TestGenerationPrefix @routes ||= begin routes = ActionDispatch::Routing::RouteSet.new routes.draw do - match "/posts/:id", :to => "posts#show", :as => :post + get "/posts/:id", :to => "posts#show", :as => :post end routes diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb index ae425dd406..302bff0696 100644 --- a/actionpack/test/dispatch/request/json_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb @@ -65,7 +65,7 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest def with_test_routing with_routing do |set| set.draw do - match ':action', :to => ::JsonParamsParsingTest::TestController + post ':action', :to => ::JsonParamsParsingTest::TestController end yield end @@ -118,7 +118,7 @@ class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest def with_test_routing(controller) with_routing do |set| set.draw do - match ':action', :to => controller + post ':action', :to => controller end yield end diff --git a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb index d144f013f5..63c5ea26a6 100644 --- a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb @@ -144,7 +144,7 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest def with_test_routing with_routing do |set| set.draw do - match ':action', :to => 'multipart_params_parsing_test/test' + post ':action', :to => 'multipart_params_parsing_test/test' end yield end diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb index f6a1475d04..d14f188e30 100644 --- a/actionpack/test/dispatch/request/query_string_parsing_test.rb +++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb @@ -109,7 +109,7 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest def assert_parses(expected, actual) with_routing do |set| set.draw do - match ':action', :to => ::QueryStringParsingTest::TestController + get ':action', :to => ::QueryStringParsingTest::TestController end get "/parse", actual diff --git a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb index 05569561d2..568e220b15 100644 --- a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb @@ -130,7 +130,7 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest def with_test_routing with_routing do |set| set.draw do - match ':action', :to => ::UrlEncodedParamsParsingTest::TestController + post ':action', :to => ::UrlEncodedParamsParsingTest::TestController end yield end diff --git a/actionpack/test/dispatch/request/xml_params_parsing_test.rb b/actionpack/test/dispatch/request/xml_params_parsing_test.rb index afd400c2a9..84823e2896 100644 --- a/actionpack/test/dispatch/request/xml_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/xml_params_parsing_test.rb @@ -106,7 +106,7 @@ class XmlParamsParsingTest < ActionDispatch::IntegrationTest def with_test_routing with_routing do |set| set.draw do - match ':action', :to => ::XmlParamsParsingTest::TestController + post ':action', :to => ::XmlParamsParsingTest::TestController end yield end @@ -155,7 +155,7 @@ class RootLessXmlParamsParsingTest < ActionDispatch::IntegrationTest def with_test_routing with_routing do |set| set.draw do - match ':action', :to => ::RootLessXmlParamsParsingTest::TestController + post ':action', :to => ::RootLessXmlParamsParsingTest::TestController end yield end diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb index 4b98cd32f2..a8050b4fab 100644 --- a/actionpack/test/dispatch/request_id_test.rb +++ b/actionpack/test/dispatch/request_id_test.rb @@ -52,7 +52,7 @@ class RequestIdResponseTest < ActionDispatch::IntegrationTest def with_test_route_set with_routing do |set| set.draw do - match '/', :to => ::RequestIdResponseTest::TestController.action(:index) + get '/', :to => ::RequestIdResponseTest::TestController.action(:index) end @app = self.class.build_app(set) do |middleware| @@ -62,4 +62,4 @@ class RequestIdResponseTest < ActionDispatch::IntegrationTest yield end end -end
\ No newline at end of file +end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 6c8b22c47f..94d0e09842 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -35,37 +35,40 @@ class RequestTest < ActiveSupport::TestCase assert_equal '1.2.3.4', request.remote_ip request = stub_request 'REMOTE_ADDR' => '1.2.3.4', - 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' + 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' assert_equal '3.4.5.6', request.remote_ip request = stub_request 'REMOTE_ADDR' => '127.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' + 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' assert_equal '3.4.5.6', request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6,unknown' assert_equal '3.4.5.6', request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '172.16.0.1,3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '192.168.0.1,3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '10.0.0.1,3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '10.0.0.1, 10.0.0.1, 3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '127.0.0.1,3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,192.168.0.1' - assert_equal 'unknown', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6, 9.9.9.9, 10.0.0.1, 172.31.4.4' assert_equal '3.4.5.6', request.remote_ip + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'not_ip_address' + assert_equal nil, request.remote_ip + request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1', 'HTTP_CLIENT_IP' => '2.2.2.2' e = assert_raise(ActionDispatch::RemoteIp::IpSpoofAttackError) { @@ -89,6 +92,68 @@ class RequestTest < ActiveSupport::TestCase assert_equal '9.9.9.9', request.remote_ip end + test "remote ip v6" do + request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334' + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334,fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip + + request = stub_request 'REMOTE_ADDR' => '::1', + 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => '::1,fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => '::1,fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => '::1,fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => '::1, ::1, fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,::1' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334, fe80:0000:0000:0000:0202:b3ff:fe1e:8329, ::1, fc00::' + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'not_ip_address' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', + 'HTTP_CLIENT_IP' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334' + e = assert_raise(ActionDispatch::RemoteIp::IpSpoofAttackError) { + request.remote_ip + } + assert_match(/IP spoofing attack/, e.message) + assert_match(/HTTP_X_FORWARDED_FOR="fe80:0000:0000:0000:0202:b3ff:fe1e:8329"/, e.message) + assert_match(/HTTP_CLIENT_IP="2001:0db8:85a3:0000:0000:8a2e:0370:7334"/, e.message) + + # Turn IP Spoofing detection off. + # This is useful for sites that are aimed at non-IP clients. The typical + # example is WAP. Since the cellular network is not IP based, it's a + # leap of faith to assume that their proxies are ever going to set the + # HTTP_CLIENT_IP/HTTP_X_FORWARDED_FOR headers properly. + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', + 'HTTP_CLIENT_IP' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + :ip_spoofing_check => false + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329, 2001:0db8:85a3:0000:0000:8a2e:0370:7334' + assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip + end + test "remote ip when the remote ip middleware returns nil" do request = stub_request 'REMOTE_ADDR' => '127.0.0.1' assert_equal '127.0.0.1', request.remote_ip @@ -97,29 +162,47 @@ class RequestTest < ActiveSupport::TestCase test "remote ip with user specified trusted proxies String" do @trusted_proxies = "67.205.106.73" - request = stub_request 'REMOTE_ADDR' => '67.205.106.73', - 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' + request = stub_request 'REMOTE_ADDR' => '3.4.5.6', + 'HTTP_X_FORWARDED_FOR' => '67.205.106.73' assert_equal '3.4.5.6', request.remote_ip request = stub_request 'REMOTE_ADDR' => '172.16.0.1,67.205.106.73', - 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip + 'HTTP_X_FORWARDED_FOR' => '67.205.106.73' + assert_equal '172.16.0.1', request.remote_ip - request = stub_request 'REMOTE_ADDR' => '67.205.106.73,172.16.0.1', - 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' - assert_equal '3.4.5.6', request.remote_ip - - request = stub_request 'REMOTE_ADDR' => '67.205.106.74,172.16.0.1', - 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' + request = stub_request 'REMOTE_ADDR' => '67.205.106.73,3.4.5.6', + 'HTTP_X_FORWARDED_FOR' => '67.205.106.73' assert_equal '3.4.5.6', request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,67.205.106.73' - assert_equal 'unknown', request.remote_ip + assert_equal nil, request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6, 9.9.9.9, 10.0.0.1, 67.205.106.73' assert_equal '3.4.5.6', request.remote_ip end + test "remote ip v6 with user specified trusted proxies String" do + @trusted_proxies = 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + + request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'REMOTE_ADDR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'REMOTE_ADDR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,::1', + 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal nil, request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334' + assert_equal nil, request.remote_ip + end + test "remote ip with user specified trusted proxies Regexp" do @trusted_proxies = /^67\.205\.106\.73$/i @@ -128,7 +211,18 @@ class RequestTest < ActiveSupport::TestCase assert_equal '3.4.5.6', request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => '67.205.106.73, 10.0.0.1, 9.9.9.9, 3.4.5.6' - assert_equal '10.0.0.1', request.remote_ip + assert_equal nil, request.remote_ip + end + + test "remote ip v6 with user specified trusted proxies Regexp" do + @trusted_proxies = /^fe80:0000:0000:0000:0202:b3ff:fe1e:8329$/i + + request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329' + assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip + + request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329, 2001:0db8:85a3:0000:0000:8a2e:0370:7334' + assert_equal nil, request.remote_ip end test "domains" do diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index cc4279d9dd..463dd6cb85 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -58,41 +58,41 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest get "remove", :action => :destroy, :as => :remove end - match 'account/logout' => redirect("/logout"), :as => :logout_redirect - match 'account/login', :to => redirect("/login") - match 'secure', :to => redirect("/secure/login") + get 'account/logout' => redirect("/logout"), :as => :logout_redirect + get 'account/login', :to => redirect("/login") + get 'secure', :to => redirect("/secure/login") - match 'mobile', :to => redirect(:subdomain => 'mobile') - match 'super_new_documentation', :to => redirect(:host => 'super-docs.com') + get 'mobile', :to => redirect(:subdomain => 'mobile') + get 'super_new_documentation', :to => redirect(:host => 'super-docs.com') - match 'youtube_favorites/:youtube_id/:name', :to => redirect(YoutubeFavoritesRedirector) + get 'youtube_favorites/:youtube_id/:name', :to => redirect(YoutubeFavoritesRedirector) constraints(lambda { |req| true }) do - match 'account/overview' + get 'account/overview' end - match '/account/nested/overview' - match 'sign_in' => "sessions#new" + get '/account/nested/overview' + get 'sign_in' => "sessions#new" - match 'account/modulo/:name', :to => redirect("/%{name}s") - match 'account/proc/:name', :to => redirect {|params, req| "/#{params[:name].pluralize}" } - match 'account/proc_req' => redirect {|params, req| "/#{req.method}" } + get 'account/modulo/:name', :to => redirect("/%{name}s") + get 'account/proc/:name', :to => redirect {|params, req| "/#{params[:name].pluralize}" } + get 'account/proc_req' => redirect {|params, req| "/#{req.method}" } - match 'account/google' => redirect('http://www.google.com/', :status => 302) + get 'account/google' => redirect('http://www.google.com/', :status => 302) match 'openid/login', :via => [:get, :post], :to => "openid#login" controller(:global) do get 'global/hide_notice' - match 'global/export', :to => :export, :as => :export_request - match '/export/:id/:file', :to => :export, :as => :export_download, :constraints => { :file => /.*/ } - match 'global/:action' + get 'global/export', :to => :export, :as => :export_request + get '/export/:id/:file', :to => :export, :as => :export_download, :constraints => { :file => /.*/ } + get 'global/:action' end - match "/local/:action", :controller => "local" + get "/local/:action", :controller => "local" - match "/projects/status(.:format)" - match "/404", :to => lambda { |env| [404, {"Content-Type" => "text/plain"}, ["NOT FOUND"]] } + get "/projects/status(.:format)" + get "/404", :to => lambda { |env| [404, {"Content-Type" => "text/plain"}, ["NOT FOUND"]] } constraints(:ip => /192\.168\.1\.\d\d\d/) do get 'admin' => "queenbee#index" @@ -277,25 +277,25 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - match 'sprockets.js' => ::TestRoutingMapper::SprocketsApp + get 'sprockets.js' => ::TestRoutingMapper::SprocketsApp - match 'people/:id/update', :to => 'people#update', :as => :update_person - match '/projects/:project_id/people/:id/update', :to => 'people#update', :as => :update_project_person + get 'people/:id/update', :to => 'people#update', :as => :update_person + get '/projects/:project_id/people/:id/update', :to => 'people#update', :as => :update_project_person # misc - match 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article + get 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article # default params - match 'inline_pages/(:id)', :to => 'pages#show', :id => 'home' - match 'default_pages/(:id)', :to => 'pages#show', :defaults => { :id => 'home' } + get 'inline_pages/(:id)', :to => 'pages#show', :id => 'home' + get 'default_pages/(:id)', :to => 'pages#show', :defaults => { :id => 'home' } defaults :id => 'home' do - match 'scoped_pages/(:id)', :to => 'pages#show' + get 'scoped_pages/(:id)', :to => 'pages#show' end namespace :account do - match 'shorthand' - match 'description', :to => :description, :as => "description" - match ':action/callback', :action => /twitter|github/, :to => "callbacks", :as => :callback + get 'shorthand' + get 'description', :to => :description, :as => "description" + get ':action/callback', :action => /twitter|github/, :to => "callbacks", :as => :callback resource :subscription, :credit, :credit_card root :to => "account#index" @@ -318,7 +318,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest controller :articles do scope '/articles', :as => 'article' do scope :path => '/:title', :title => /[a-z]+/, :as => :with_title do - match '/:id', :to => :with_id, :as => "" + get '/:id', :to => :with_id, :as => "" end end end @@ -327,7 +327,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resources :rooms end - match '/info' => 'projects#info', :as => 'info' + get '/info' => 'projects#info', :as => 'info' namespace :admin do scope '(:locale)', :locale => /en|pl/ do @@ -361,7 +361,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest scope :path => 'api' do resource :me - match '/' => 'mes#index' + get '/' => 'mes#index' end get "(/:username)/followers" => "followers#index" @@ -374,7 +374,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - match "whatever/:controller(/:action(/:id))", :id => /\d+/ + get "whatever/:controller(/:action(/:id))", :id => /\d+/ resource :profile do get :settings @@ -407,7 +407,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest namespace :private do root :to => redirect('/private/index') - match "index", :to => 'private#index' + get "index", :to => 'private#index' end scope :only => [:index, :show] do @@ -489,7 +489,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest get "/forced_collision", :as => :forced_collision, :to => "forced_collision#show" end - match '/purchases/:token/:filename', + get '/purchases/:token/:filename', :to => 'purchases#fetch', :token => /[[:alnum:]]{10}/, :filename => /(.+)/, @@ -500,18 +500,18 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end scope '/countries/:country', :constraints => lambda { |params, req| params[:country].in?(["all", "France"]) } do - match '/', :to => 'countries#index' - match '/cities', :to => 'countries#cities' + get '/', :to => 'countries#index' + get '/cities', :to => 'countries#cities' end - match '/countries/:country/(*other)', :to => redirect{ |params, req| params[:other] ? "/countries/all/#{params[:other]}" : '/countries/all' } + get '/countries/:country/(*other)', :to => redirect{ |params, req| params[:other] ? "/countries/all/#{params[:other]}" : '/countries/all' } - match '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/ + get '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/ scope '/italians' do - match '/writers', :to => 'italians#writers', :constraints => ::TestRoutingMapper::IpRestrictor - match '/sculptors', :to => 'italians#sculptors' - match '/painters/:painter', :to => 'italians#painters', :constraints => {:painter => /michelangelo/} + get '/writers', :to => 'italians#writers', :constraints => ::TestRoutingMapper::IpRestrictor + get '/sculptors', :to => 'italians#sculptors' + get '/painters/:painter', :to => 'italians#painters', :constraints => {:painter => /michelangelo/} end end end @@ -627,7 +627,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest self.class.stub_controllers do |routes| routes.draw do namespace :admin do - match '/:controller(/:action(/:id(.:format)))' + get '/:controller(/:action(/:id(.:format)))' end end end @@ -2231,12 +2231,12 @@ class TestAppendingRoutes < ActionDispatch::IntegrationTest s = self @app = ActionDispatch::Routing::RouteSet.new @app.append do - match '/hello' => s.simple_app('fail') - match '/goodbye' => s.simple_app('goodbye') + get '/hello' => s.simple_app('fail') + get '/goodbye' => s.simple_app('goodbye') end @app.draw do - match '/hello' => s.simple_app('hello') + get '/hello' => s.simple_app('hello') end end @@ -2344,12 +2344,12 @@ end class TestUriPathEscaping < ActionDispatch::IntegrationTest Routes = ActionDispatch::Routing::RouteSet.new.tap do |app| app.draw do - match '/:segment' => lambda { |env| + get '/:segment' => lambda { |env| path_params = env['action_dispatch.request.path_parameters'] [200, { 'Content-Type' => 'text/plain' }, [path_params[:segment]]] }, :as => :segment - match '/*splat' => lambda { |env| + get '/*splat' => lambda { |env| path_params = env['action_dispatch.request.path_parameters'] [200, { 'Content-Type' => 'text/plain' }, [path_params[:splat]]] }, :as => :splat @@ -2381,7 +2381,7 @@ end class TestUnicodePaths < ActionDispatch::IntegrationTest Routes = ActionDispatch::Routing::RouteSet.new.tap do |app| app.draw do - match "/#{Rack::Utils.escape("ほげ")}" => lambda { |env| + get "/#{Rack::Utils.escape("ほげ")}" => lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }, :as => :unicode_path end @@ -2411,10 +2411,10 @@ class TestMultipleNestedController < ActionDispatch::IntegrationTest app.draw do namespace :foo do namespace :bar do - match "baz" => "baz#index" + get "baz" => "baz#index" end end - match "pooh" => "pooh#index" + get "pooh" => "pooh#index" end end @@ -2433,8 +2433,8 @@ class TestTildeAndMinusPaths < ActionDispatch::IntegrationTest app.draw do ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] } - match "/~user" => ok - match "/young-and-fine" => ok + get "/~user" => ok + get "/young-and-fine" => ok end end diff --git a/actionpack/test/dispatch/session/cache_store_test.rb b/actionpack/test/dispatch/session/cache_store_test.rb index 12405bf45d..a74e165826 100644 --- a/actionpack/test/dispatch/session/cache_store_test.rb +++ b/actionpack/test/dispatch/session/cache_store_test.rb @@ -164,7 +164,7 @@ class CacheStoreTest < ActionDispatch::IntegrationTest def with_test_route_set with_routing do |set| set.draw do - match ':action', :to => ::CacheStoreTest::TestController + get ':action', :to => ::CacheStoreTest::TestController end @app = self.class.build_app(set) do |middleware| diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb index 19969394cd..631974d6c4 100644 --- a/actionpack/test/dispatch/session/cookie_store_test.rb +++ b/actionpack/test/dispatch/session/cookie_store_test.rb @@ -317,7 +317,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest def with_test_route_set(options = {}) with_routing do |set| set.draw do - match ':action', :to => ::CookieStoreTest::TestController + get ':action', :to => ::CookieStoreTest::TestController end options = { :key => SessionKey }.merge!(options) diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb index 5277c92b55..03234612ab 100644 --- a/actionpack/test/dispatch/session/mem_cache_store_test.rb +++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb @@ -173,7 +173,7 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest def with_test_route_set with_routing do |set| set.draw do - match ':action', :to => ::MemCacheStoreTest::TestController + get ':action', :to => ::MemCacheStoreTest::TestController end @app = self.class.build_app(set) do |middleware| diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb index 2b54bc62b0..985ff2e81a 100644 --- a/actionpack/test/dispatch/url_generation_test.rb +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -3,7 +3,7 @@ require 'abstract_unit' module TestUrlGeneration class WithMountPoint < ActionDispatch::IntegrationTest Routes = ActionDispatch::Routing::RouteSet.new - Routes.draw { match "/foo", :to => "my_route_generating#index", :as => :foo } + Routes.draw { get "/foo", :to => "my_route_generating#index", :as => :foo } class ::MyRouteGeneratingController < ActionController::Base include Routes.url_helpers diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 3fa3898ec8..a714264909 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -97,7 +97,7 @@ class FormHelperTest < ActionView::TestCase end end - match "/foo", :to => "controller#action" + get "/foo", :to => "controller#action" root :to => "main#index" end diff --git a/actionpack/test/template/test_test.rb b/actionpack/test/template/test_test.rb index adcbf1447f..108a674d95 100644 --- a/actionpack/test/template/test_test.rb +++ b/actionpack/test/template/test_test.rb @@ -48,7 +48,7 @@ class PeopleHelperTest < ActionView::TestCase def with_test_route_set with_routing do |set| set.draw do - match 'people', :to => 'people#index', :as => :people + get 'people', :to => 'people#index', :as => :people end yield end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 88f506b217..eaa8bdbd26 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -15,9 +15,9 @@ class UrlHelperTest < ActiveSupport::TestCase routes = ActionDispatch::Routing::RouteSet.new routes.draw do - match "/" => "foo#bar" - match "/other" => "foo#other" - match "/article/:id" => "foo#article", :as => :article + get "/" => "foo#bar" + get "/other" => "foo#other" + get "/article/:id" => "foo#article", :as => :article end include routes.url_helpers @@ -471,25 +471,25 @@ end class UrlHelperControllerTest < ActionController::TestCase class UrlHelperController < ActionController::Base test_routes do - match 'url_helper_controller_test/url_helper/show/:id', + get 'url_helper_controller_test/url_helper/show/:id', :to => 'url_helper_controller_test/url_helper#show', :as => :show - match 'url_helper_controller_test/url_helper/profile/:name', + get 'url_helper_controller_test/url_helper/profile/:name', :to => 'url_helper_controller_test/url_helper#show', :as => :profile - match 'url_helper_controller_test/url_helper/show_named_route', + get 'url_helper_controller_test/url_helper/show_named_route', :to => 'url_helper_controller_test/url_helper#show_named_route', :as => :show_named_route - match "/:controller(/:action(/:id))" + get "/:controller(/:action(/:id))" - match 'url_helper_controller_test/url_helper/normalize_recall_params', + get 'url_helper_controller_test/url_helper/normalize_recall_params', :to => UrlHelperController.action(:normalize_recall), :as => :normalize_recall_params - match '/url_helper_controller_test/url_helper/override_url_helper/default', + get '/url_helper_controller_test/url_helper/override_url_helper/default', :to => 'url_helper_controller_test/url_helper#override_url_helper', :as => :override_url_helper end diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index 7d13a0123b..9b05384792 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -26,7 +26,7 @@ to integrate with Action Pack out of the box: <tt>ActiveModel::Model</tt>. person = Person.new(:name => 'bob', :age => '18') person.name # => 'bob' person.age # => 18 - person.valid? # => false + person.valid? # => true It includes model name introspections, conversions, translations and validations, resulting in a class suitable to be used with Action Pack. @@ -116,9 +116,6 @@ behavior out of the box: person.errors.full_messages # => ["Name can not be nil"] - person.errors.full_messages - # => ["Name can not be nil"] - {Learn more}[link:classes/ActiveModel/Errors.html] * Model name introspection diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb index fc84b52dd9..35b1a1f0c7 100644 --- a/activemodel/lib/active_model/observing.rb +++ b/activemodel/lib/active_model/observing.rb @@ -4,6 +4,8 @@ require 'active_support/core_ext/module/aliasing' require 'active_support/core_ext/module/remove_method' require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/enumerable' +require 'active_support/deprecation' +require 'active_support/core_ext/object/try' require 'active_support/descendants_tracker' module ActiveModel @@ -74,10 +76,16 @@ module ActiveModel end # Total number of observers. - def count_observers + def observers_count observer_instances.size end + def count_observers + msg = "count_observers is deprecated in favor of observers_count" + ActiveSupport::Deprecation.warn(msg) + observers_count + end + protected def instantiate_observer(observer) #:nodoc: # string/symbol @@ -205,11 +213,7 @@ module ActiveModel # The class observed by default is inferred from the observer's class name: # assert_equal Person, PersonObserver.observed_class def observed_class - if observed_class_name = name[/(.*)Observer/, 1] - observed_class_name.constantize - else - nil - end + name[/(.*)Observer/, 1].try :constantize end end diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb index ff2213231f..8711b24124 100644 --- a/activemodel/lib/active_model/secure_password.rb +++ b/activemodel/lib/active_model/secure_password.rb @@ -58,7 +58,8 @@ module ActiveModel BCrypt::Password.new(password_digest) == unencrypted_password && self end - # Encrypts the password into the password_digest attribute. + # Encrypts the password into the password_digest attribute, only if the + # new password is not blank. def password=(unencrypted_password) unless unencrypted_password.blank? @password = unencrypted_password diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index 4323ee1e09..a5828476b1 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -26,17 +26,18 @@ module ActiveModel # person.serializable_hash # => {"name"=>"Bob"} # # You need to declare an attributes hash which contains the attributes - # you want to serialize. When called, serializable hash will use + # you want to serialize. Attributes must be strings, not symbols. + # When called, serializable hash will use # instance methods that match the name of the attributes hash's keys. # In order to override this behavior, take a look at the private - # method read_attribute_for_serialization. + # method +read_attribute_for_serialization+. # # Most of the time though, you will want to include the JSON or XML # serializations. Both of these modules automatically include the - # ActiveModel::Serialization module, so there is no need to explicitly + # +ActiveModel::Serialization+ module, so there is no need to explicitly # include it. # - # So a minimal implementation including XML and JSON would be: + # A minimal implementation including XML and JSON would be: # # class Person # include ActiveModel::Serializers::JSON @@ -63,7 +64,12 @@ module ActiveModel # person.to_json # => "{\"name\":\"Bob\"}" # person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person... # - # Valid options are <tt>:only</tt>, <tt>:except</tt> and <tt>:methods</tt> . + # Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and <tt>include</tt>. + # The following are all valid examples: + # + # person.serializable_hash(:only => 'name') + # person.serializable_hash(:include => :address) + # person.serializable_hash(:include => { :address => { :only => 'city' }}) module Serialization def serializable_hash(options = nil) options ||= {} @@ -78,8 +84,7 @@ module ActiveModel hash = {} attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) } - method_names = Array(options[:methods]).select { |n| respond_to?(n) } - method_names.each { |n| hash[n.to_s] = send(n) } + Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) } serializable_add_includes(options) do |association, records, opts| hash[association.to_s] = if records.is_a?(Enumerable) diff --git a/activemodel/test/cases/observing_test.rb b/activemodel/test/cases/observing_test.rb index f6ec24ae57..df070d2d8e 100644 --- a/activemodel/test/cases/observing_test.rb +++ b/activemodel/test/cases/observing_test.rb @@ -73,7 +73,7 @@ class ObservingTest < ActiveModel::TestCase test "passes observers to subclasses" do FooObserver.instance bar = Class.new(Foo) - assert_equal Foo.count_observers, bar.count_observers + assert_equal Foo.observers_count, bar.observers_count end end diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb index 4e09a43f8e..e75003f261 100644 --- a/activerecord/lib/active_record/associations/association.rb +++ b/activerecord/lib/active_record/associations/association.rb @@ -132,7 +132,8 @@ module ActiveRecord # ActiveRecord::RecordNotFound is rescued within the method, and it is # not reraised. The proxy is \reset and +nil+ is the return value. def load_target - @target ||= find_target if find_target? + @target = find_target if (@stale_state && stale_target?) || find_target? + loaded! unless loaded? target rescue ActiveRecord::RecordNotFound diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 81c6e400d2..ddfc6f6c05 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -77,7 +77,7 @@ module ActiveRecord end def stale_state - owner[reflection.foreign_key].to_s + owner[reflection.foreign_key] && owner[reflection.foreign_key].to_s end end end diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb index 2ee5dbbd70..88ce03a3cd 100644 --- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb @@ -27,7 +27,8 @@ module ActiveRecord end def stale_state - [super, owner[reflection.foreign_type].to_s] + foreign_key = super + foreign_key && [foreign_key.to_s, owner[reflection.foreign_type].to_s] end end end diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index 5eda0387c4..44cbf473a1 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -126,6 +126,19 @@ module ActiveRecord proxy_association.reload self end + + # Define array public methods because we know it should be invoked over + # the target, so we can have a performance improvement using those methods + # in association collections + Array.public_instance_methods.each do |m| + unless method_defined?(m) + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{m}(*args, &block) + target.public_send(:#{m}, *args, &block) if load_target + end + RUBY + end + end end end end diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index fd0e90aaf0..be890e5767 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -62,7 +62,7 @@ module ActiveRecord # properly support stale-checking for nested associations. def stale_state if through_reflection.macro == :belongs_to - owner[through_reflection.foreign_key].to_s + owner[through_reflection.foreign_key] && owner[through_reflection.foreign_key].to_s end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 1d713e472b..c6faae77cc 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -163,11 +163,6 @@ module ActiveRecord # QUOTING ================================================== - # Override to return the quoted table name. Defaults to column quoting. - def quote_table_name(name) - quote_column_name(name) - end - # Returns a bind substitution value given a +column+ and list of current # +binds+ def substitute_at(column, index) @@ -299,7 +294,7 @@ module ActiveRecord raise exception end - def translate_exception(e, message) + def translate_exception(exception, message) # override in derived class ActiveRecord::StatementInvalid.new(message) end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 0dbaab306f..333d31d8a3 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -236,7 +236,10 @@ module ActiveRecord # Please check unscoped if you want to remove all previous scopes (including # the default_scope) during the execution of a block. def scoping - @klass.with_scope(self, :overwrite) { yield } + previous, klass.current_scope = klass.current_scope, self + yield + ensure + klass.current_scope = previous end # Updates all records with details given if they match a set of conditions supplied, limits and order can diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb index 1c2a06328f..3f880ce5e9 100644 --- a/activerecord/lib/active_record/relation/merger.rb +++ b/activerecord/lib/active_record/relation/merger.rb @@ -3,32 +3,41 @@ require 'active_support/core_ext/hash/keys' module ActiveRecord class Relation - class Merger - attr_reader :relation, :other + class HashMerger + attr_reader :relation, :hash - def initialize(relation, other) - @relation = relation + def initialize(relation, hash) + hash.assert_valid_keys(*Relation::VALUE_METHODS) - if other.default_scoped? && other.klass != relation.klass - @other = other.with_default_scope - else - @other = other - end + @relation = relation + @hash = hash end def merge - HashMerger.new(relation, other.values).merge + Merger.new(relation, other).merge + end + + # Applying values to a relation has some side effects. E.g. + # interpolation might take place for where values. So we should + # build a relation to merge in rather than directly merging + # the values. + def other + other = Relation.new(relation.klass, relation.table) + hash.each { |k, v| other.send("#{k}!", v) } + other end end - class HashMerger + class Merger attr_reader :relation, :values - def initialize(relation, values) - values.assert_valid_keys(*Relation::VALUE_METHODS) + def initialize(relation, other) + if other.default_scoped? && other.klass != relation.klass + other = other.with_default_scope + end @relation = relation - @values = values + @values = other.values end def normal_values diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 1d2151fdb2..41e55dfd0e 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -30,11 +30,8 @@ module ActiveRecord end def merge!(other) - if other.is_a?(Hash) - Relation::HashMerger.new(self, other).merge - else - Relation::Merger.new(self, other).merge - end + klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger + klass.new(self, other).merge end # Removes from the query the condition(s) specified in +skips+. diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb index a8f5e96190..66a486ae0a 100644 --- a/activerecord/lib/active_record/scoping.rb +++ b/activerecord/lib/active_record/scoping.rb @@ -10,118 +10,6 @@ module ActiveRecord end module ClassMethods - # with_scope lets you apply options to inner block incrementally. It takes a hash and the keys must be - # <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameter is <tt>Relation</tt> while - # <tt>:create</tt> parameters are an attributes hash. - # - # class Article < ActiveRecord::Base - # def self.create_with_scope - # with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do - # find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1 - # a = create(1) - # a.blog_id # => 1 - # end - # end - # end - # - # In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of - # <tt>where</tt>, <tt>includes</tt>, and <tt>joins</tt> operations in <tt>Relation</tt>, which are merged. - # - # <tt>joins</tt> operations are uniqued so multiple scopes can join in the same table without table aliasing - # problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the - # array of strings format for your joins. - # - # class Article < ActiveRecord::Base - # def self.find_with_scope - # with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do - # with_scope(:find => limit(10)) do - # all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10 - # end - # with_scope(:find => where(:author_id => 3)) do - # all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1 - # end - # end - # end - # end - # - # You can ignore any previous scopings by using the <tt>with_exclusive_scope</tt> method. - # - # class Article < ActiveRecord::Base - # def self.find_with_exclusive_scope - # with_scope(:find => where(:blog_id => 1).limit(1)) do - # with_exclusive_scope(:find => limit(10)) do - # all # => SELECT * from articles LIMIT 10 - # end - # end - # end - # end - # - # *Note*: the +:find+ scope also has effect on update and deletion methods, like +update_all+ and +delete_all+. - def with_scope(scope = {}, action = :merge, &block) - # If another Active Record class has been passed in, get its current scope - scope = scope.current_scope if !scope.is_a?(Relation) && scope.respond_to?(:current_scope) - - previous_scope = self.current_scope - - if scope.is_a?(Hash) - # Dup first and second level of hash (method and params). - scope = scope.dup - scope.each do |method, params| - scope[method] = params.dup unless params == true - end - - scope.assert_valid_keys([ :find, :create ]) - relation = construct_finder_arel(scope[:find] || {}) - relation.default_scoped = true unless action == :overwrite - - if previous_scope && previous_scope.create_with_value && scope[:create] - scope_for_create = if action == :merge - previous_scope.create_with_value.merge(scope[:create]) - else - scope[:create] - end - - relation = relation.create_with(scope_for_create) - else - scope_for_create = scope[:create] - scope_for_create ||= previous_scope.create_with_value if previous_scope - relation = relation.create_with(scope_for_create) if scope_for_create - end - - scope = relation - end - - scope = previous_scope.merge(scope) if previous_scope && action == :merge - - self.current_scope = scope - begin - yield - ensure - self.current_scope = previous_scope - end - end - - protected - - # Works like with_scope, but discards any nested properties. - def with_exclusive_scope(method_scoping = {}, &block) - if method_scoping.values.any? { |e| e.is_a?(ActiveRecord::Relation) } - raise ArgumentError, <<-MSG - New finder API can not be used with_exclusive_scope. You can either call unscoped to get an anonymous scope not bound to the default_scope: - - User.unscoped.where(:active => true) - - Or call unscoped with a block: - - User.unscoped do - User.where(:active => true).all - end - - MSG - end - with_scope(method_scoping, :overwrite, &block) - end - def current_scope #:nodoc: Thread.current["#{self}_current_scope"] end @@ -129,15 +17,6 @@ module ActiveRecord def current_scope=(scope) #:nodoc: Thread.current["#{self}_current_scope"] = scope end - - private - - def construct_finder_arel(options = {}, scope = nil) - relation = options.is_a?(Hash) ? unscoped.apply_finder_options(options) : options - relation = scope.merge(relation) if scope - relation - end - end def populate_with_current_scope_attributes diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb index 45c34005c3..db833fc7f1 100644 --- a/activerecord/lib/active_record/scoping/default.rb +++ b/activerecord/lib/active_record/scoping/default.rb @@ -87,7 +87,7 @@ module ActiveRecord # # Should return a scope, you can call 'super' here etc. # end # end - def default_scope(scope = {}) + def default_scope(scope = nil) scope = Proc.new if block_given? if scope.is_a?(Relation) || !scope.respond_to?(:call) @@ -103,14 +103,13 @@ module ActiveRecord end def build_default_scope #:nodoc: - if method(:default_scope).owner != ActiveRecord::Scoping::Default::ClassMethods + if !Base.is_a?(method(:default_scope).owner) + # The user has defined their own default scope method, so call that evaluate_default_scope { default_scope } elsif default_scopes.any? evaluate_default_scope do default_scopes.inject(relation) do |default_scope, scope| - if scope.is_a?(Hash) - default_scope.apply_finder_options(scope) - elsif !scope.is_a?(Relation) && scope.respond_to?(:call) + if !scope.is_a?(Relation) && scope.respond_to?(:call) default_scope.merge(unscoped { scope.call }) else default_scope.merge(scope) diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb index b43e08157a..2af476c1ba 100644 --- a/activerecord/lib/active_record/scoping/named.rb +++ b/activerecord/lib/active_record/scoping/named.rb @@ -29,17 +29,16 @@ module ActiveRecord # You can define a \scope that applies to all finders using # ActiveRecord::Base.default_scope. def scoped(options = nil) - if options - scoped.apply_finder_options(options) + if current_scope + scope = current_scope.clone else - if current_scope - current_scope.clone - else - scope = relation - scope.default_scoped = true - scope - end + scope = relation + scope.default_scoped = true + scope end + + scope.merge!(options) if options + scope end ## @@ -172,7 +171,7 @@ module ActiveRecord # Article.published.featured.latest_article # Article.featured.titles - def scope(name, body = {}, &block) + def scope(name, body, &block) extension = Module.new(&block) if block # Check body.is_a?(Relation) to prevent the relation actually being @@ -189,9 +188,7 @@ module ActiveRecord end singleton_class.send(:define_method, name) do |*args| - options = body.respond_to?(:call) ? unscoped { body.call(*args) } : body - options = scoped.apply_finder_options(options) if options.is_a?(Hash) - + options = body.respond_to?(:call) ? unscoped { body.call(*args) } : body relation = scoped.merge(options) extension ? relation.extending(extension) : relation diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 9dd041af81..05ab86105c 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -705,4 +705,27 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal toy, sponsor.reload.sponsorable end + + test "stale tracking doesn't care about the type" do + apple = Firm.create("name" => "Apple") + citibank = Account.create("credit_limit" => 10) + + citibank.firm_id = apple.id + citibank.firm # load it + + citibank.firm_id = apple.id.to_s + + assert !citibank.association(:firm).stale_target? + end + + def test_reflect_the_most_recent_change + author1, author2 = Author.limit(2) + post = Post.new(:title => "foo", :body=> "bar") + + post.author = author1 + post.author_id = author2.id + + assert post.save + assert_equal post.author_id, author2.id + end end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index ef22936e18..024225b813 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -2087,4 +2087,9 @@ class BasicsTest < ActiveRecord::TestCase assert_equal record, klass.public_send(meth, :foo, :bar) end end + + test "scoped can take a values hash" do + klass = Class.new(ActiveRecord::Base) + assert_equal ['foo'], klass.scoped(select: 'foo').select_values + end end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 0d3c0b20a4..06d076943e 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -460,21 +460,16 @@ class NamedScopeTest < ActiveRecord::TestCase klass.table_name = 'posts' assert_deprecated do - klass.scope :welcome, { :conditions => { :id => posts(:welcome).id } } - end - assert_equal [posts(:welcome).title], klass.welcome.map(&:title) - - assert_deprecated do klass.scope :welcome_2, klass.where(:id => posts(:welcome).id) end assert_equal [posts(:welcome).title], klass.welcome_2.map(&:title) end - def test_eager_default_scope_hashes_are_deprecated + def test_eager_default_scope_hashes_are_not_deprecated klass = Class.new(ActiveRecord::Base) klass.table_name = 'posts' - assert_deprecated do + assert_not_deprecated do klass.send(:default_scope, :conditions => { :id => posts(:welcome).id }) end assert_equal [posts(:welcome).title], klass.all.map(&:title) diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 9ef703fd9b..8a7a2441d4 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -130,9 +130,9 @@ module ActiveRecord test 'merging a hash into a relation' do relation = Relation.new :a, :b - relation = relation.merge where: ['lol'], readonly: true + relation = relation.merge where: :lol, readonly: true - assert_equal ['lol'], relation.where_values + assert_equal [:lol], relation.where_values assert_equal true, relation.readonly_value end @@ -156,6 +156,21 @@ module ActiveRecord relation = Relation.new(:a, :b, where: [:foo]) assert_equal [:foo], relation.where_values end + + test 'merging a single where value' do + relation = Relation.new(:a, :b) + relation.merge!(where: :foo) + assert_equal [:foo], relation.where_values + end + + test 'merging a hash interpolates conditions' do + klass = stub + klass.stubs(:sanitize_sql).with(['foo = ?', 'bar']).returns('foo = bar') + + relation = Relation.new(klass, :b) + relation.merge!(where: ['foo = ?', 'bar']) + assert_equal ['foo = bar'], relation.where_values + end end class RelationMutationTest < ActiveSupport::TestCase @@ -221,8 +236,8 @@ module ActiveRecord end test 'merge!' do - assert relation.merge!(where: ['foo']).equal?(relation) - assert_equal ['foo'], relation.where_values + assert relation.merge!(where: :foo).equal?(relation) + assert_equal [:foo], relation.where_values end end end diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb index 785839be75..0625b8d296 100644 --- a/activerecord/test/models/topic.rb +++ b/activerecord/test/models/topic.rb @@ -45,8 +45,8 @@ class Topic < ActiveRecord::Base 2 end end - scope :named_extension, -> { { :extend => NamedExtension } } - scope :multiple_extensions, -> { { :extend => [MultipleExtensionTwo, MultipleExtensionOne] } } + scope :named_extension, :extend => NamedExtension + scope :multiple_extensions, :extend => [MultipleExtensionTwo, MultipleExtensionOne] has_many :replies, :dependent => :destroy, :foreign_key => "parent_id" has_many :replies_with_primary_key, :class_name => "Reply", :dependent => :destroy, :primary_key => "title", :foreign_key => "parent_title" diff --git a/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/activesupport/lib/active_support/core_ext/kernel/debugger.rb index d5b590e9f0..2073cac98d 100644 --- a/activesupport/lib/active_support/core_ext/kernel/debugger.rb +++ b/activesupport/lib/active_support/core_ext/kernel/debugger.rb @@ -1,8 +1,8 @@ module Kernel unless respond_to?(:debugger) - # Starts a debugging session if ruby-debug has been loaded (call rails server --debugger to do load it). + # Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it). def debugger - message = "\n***** Debugger requested, but was not available (ensure ruby-debug19 is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n" + message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n" defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message) end alias breakpoint debugger unless respond_to?(:breakpoint) diff --git a/guides/assets/images/favicon.ico b/guides/assets/images/favicon.ico Binary files differnew file mode 100644 index 0000000000..e0e80cf8f1 --- /dev/null +++ b/guides/assets/images/favicon.ico diff --git a/guides/assets/images/getting_started/index_action_with_edit_link.png b/guides/assets/images/getting_started/index_action_with_edit_link.png Binary files differnew file mode 100644 index 0000000000..6e58a13756 --- /dev/null +++ b/guides/assets/images/getting_started/index_action_with_edit_link.png diff --git a/guides/code/getting_started/Gemfile b/guides/code/getting_started/Gemfile index ab4e34b2d0..670a8523b0 100644 --- a/guides/code/getting_started/Gemfile +++ b/guides/code/getting_started/Gemfile @@ -35,4 +35,4 @@ gem 'jquery-rails' # gem 'capistrano' # To use debugger -# gem 'ruby-debug19', :require => 'ruby-debug' +# gem 'debugger' diff --git a/guides/code/getting_started/README.rdoc b/guides/code/getting_started/README.rdoc index d2014bd35f..b5d7b6436b 100644 --- a/guides/code/getting_started/README.rdoc +++ b/guides/code/getting_started/README.rdoc @@ -86,8 +86,8 @@ programming in general. Debugger support is available through the debugger command when you start your Mongrel or WEBrick server with --debugger. This means that you can break out of execution at any point in the code, investigate and change the model, and then, -resume execution! You need to install ruby-debug19 to run the server in debugging -mode. With gems, use <tt>sudo gem install ruby-debug19</tt>. Example: +resume execution! You need to install the 'debugger' gem to run the server in debugging +mode. Add gem 'debugger' to your Gemfile and run <tt>bundle</tt> to install it. Example: class WeblogController < ActionController::Base def index diff --git a/guides/code/getting_started/app/controllers/posts_controller.rb b/guides/code/getting_started/app/controllers/posts_controller.rb index 947cd2a767..fc71e9b4e8 100644 --- a/guides/code/getting_started/app/controllers/posts_controller.rb +++ b/guides/code/getting_started/app/controllers/posts_controller.rb @@ -21,4 +21,18 @@ class PostsController < ApplicationController render 'new' end end + + def edit + @post = Post.find(params[:id]) + end + + def update + @post = Post.find(params[:id]) + + if @post.update_attributes(params[:post]) + redirect_to :action => :show, :id => @post.id + else + render 'edit' + end + end end diff --git a/guides/code/getting_started/app/helpers/home_helper.rb b/guides/code/getting_started/app/helpers/welcome_helper.rb index eeead45fc9..eeead45fc9 100644 --- a/guides/code/getting_started/app/helpers/home_helper.rb +++ b/guides/code/getting_started/app/helpers/welcome_helper.rb diff --git a/guides/code/getting_started/app/views/posts/_form.html.erb b/guides/code/getting_started/app/views/posts/_form.html.erb index 18cb29f335..46ec257b91 100644 --- a/guides/code/getting_started/app/views/posts/_form.html.erb +++ b/guides/code/getting_started/app/views/posts/_form.html.erb @@ -1,4 +1,4 @@ -<%= form_for :post, :url => { :action => :create } do |f| %> +<%= form_for :post, :url => { :action => :update, :id => @post.id }, :method => :put do |f| %> <% if @post.errors.any? %> <div id="errorExplanation"> <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2> diff --git a/guides/code/getting_started/app/views/posts/edit.html.erb b/guides/code/getting_started/app/views/posts/edit.html.erb index 720580236b..911a48569d 100644 --- a/guides/code/getting_started/app/views/posts/edit.html.erb +++ b/guides/code/getting_started/app/views/posts/edit.html.erb @@ -2,5 +2,4 @@ <%= render 'form' %> -<%= link_to 'Show', @post %> | -<%= link_to 'Back', posts_path %> +<%= link_to 'Back', :action => :index %> diff --git a/guides/code/getting_started/app/views/posts/index.html.erb b/guides/code/getting_started/app/views/posts/index.html.erb index 455a74b17f..3ba7091c15 100644 --- a/guides/code/getting_started/app/views/posts/index.html.erb +++ b/guides/code/getting_started/app/views/posts/index.html.erb @@ -7,6 +7,7 @@ <th>Title</th> <th>Text</th> <th></th> + <th></th> </tr> <% @posts.each do |post| %> @@ -14,6 +15,7 @@ <td><%= post.title %></td> <td><%= post.text %></td> <td><%= link_to 'Show', :action => :show, :id => post.id %> + <td><%= link_to 'Edit', :action => :edit, :id => post.id %> </tr> <% end %> </table> diff --git a/guides/code/getting_started/app/views/posts/show.html.erb b/guides/code/getting_started/app/views/posts/show.html.erb index a79fadfe4c..aea28cd5a2 100644 --- a/guides/code/getting_started/app/views/posts/show.html.erb +++ b/guides/code/getting_started/app/views/posts/show.html.erb @@ -9,3 +9,4 @@ </p> <%= link_to 'Back', :action => :index %> +| <%= link_to 'Edit', :action => :edit, :id => @post.id %> diff --git a/guides/code/getting_started/config/routes.rb b/guides/code/getting_started/config/routes.rb index 10009a35cf..b0973c62d5 100644 --- a/guides/code/getting_started/config/routes.rb +++ b/guides/code/getting_started/config/routes.rb @@ -7,6 +7,8 @@ Blog::Application.routes.draw do get "posts/new" post "posts/create" get "posts/:id" => "posts#show" + get "posts/:id/edit" => "posts#edit" + put "posts/:id/update" => "posts#update" # The priority is based upon order of creation: # first created -> highest priority. diff --git a/guides/source/active_record_querying.textile b/guides/source/active_record_querying.textile index 58eae2ee0f..98937266ba 100644 --- a/guides/source/active_record_querying.textile +++ b/guides/source/active_record_querying.textile @@ -388,6 +388,8 @@ The field name can also be a string: Client.where('locked' => true) </ruby> +NOTE: The values cannot be symbols. For example, you cannot do +Client.where(:status => :active)+. + h5(#hash-range_conditions). Range Conditions The good thing about this is that we can pass in a range for our fields without it generating a large query as shown in the preamble of this section. diff --git a/guides/source/debugging_rails_applications.textile b/guides/source/debugging_rails_applications.textile index 57c7786636..903ed59e7b 100644 --- a/guides/source/debugging_rails_applications.textile +++ b/guides/source/debugging_rails_applications.textile @@ -191,7 +191,7 @@ Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localh Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels, to avoid filling your production logs with useless trivia. -h3. Debugging with +ruby-debug+ +h3. Debugging with the +debugger+ gem When your code is behaving in unexpected ways, you can try printing to logs or the console to diagnose the problem. Unfortunately, there are times when this sort of error tracking is not effective in finding the root cause of a problem. When you actually need to journey into your running source code, the debugger is your best companion. @@ -199,17 +199,13 @@ The debugger can also help you if you want to learn about the Rails source code h4. Setup -The debugger used by Rails, +ruby-debug+, comes as a gem. To install it, just run: +Rails uses the +debugger+ gem to set breakpoints and step through live code. To install it, just run: <shell> -$ sudo gem install ruby-debug +$ gem install debugger </shell> -TIP: If you are using Ruby 1.9, you can install a compatible version of +ruby-debug+ by running +sudo gem install ruby-debug19+ - -In case you want to download a particular version or get the source code, refer to the "project's page on rubyforge":http://rubyforge.org/projects/ruby-debug/. - -Rails has had built-in support for ruby-debug since Rails 2.0. Inside any Rails application you can invoke the debugger by calling the +debugger+ method. +Rails has had built-in support for debugging since Rails 2.0. Inside any Rails application you can invoke the debugger by calling the +debugger+ method. Here's an example: @@ -238,11 +234,11 @@ $ rails server --debugger ... </shell> -TIP: In development mode, you can dynamically +require \'ruby-debug\'+ instead of restarting the server, if it was started without +--debugger+. +TIP: In development mode, you can dynamically +require \'debugger\'+ instead of restarting the server, if it was started without +--debugger+. h4. The Shell -As soon as your application calls the +debugger+ method, the debugger will be started in a debugger shell inside the terminal window where you launched your application server, and you will be placed at ruby-debug's prompt +(rdb:n)+. The _n_ is the thread number. The prompt will also show you the next line of code that is waiting to run. +As soon as your application calls the +debugger+ method, the debugger will be started in a debugger shell inside the terminal window where you launched your application server, and you will be placed at the debugger's prompt +(rdb:n)+. The _n_ is the thread number. The prompt will also show you the next line of code that is waiting to run. If you got there by a browser request, the browser tab containing the request will be hung until the debugger has finished and the trace has finished processing the entire request. @@ -270,7 +266,7 @@ continue edit frame method putl set tmate where TIP: To view the help menu for any command use +help <command-name>+ in active debug mode. For example: _+help var+_ -The next command to learn is one of the most useful: +list+. You can also abbreviate ruby-debug commands by supplying just enough letters to distinguish them from other commands, so you can also use +l+ for the +list+ command. +The next command to learn is one of the most useful: +list+. You can abbreviate any debugging command by supplying just enough letters to distinguish them from other commands, so you can also use +l+ for the +list+ command. This command shows you where you are in the code by printing 10 lines centered around the current line; the current line in this particular case is line 6 and is marked by +=>+. @@ -347,7 +343,7 @@ h4. The Context When you start debugging your application, you will be placed in different contexts as you go through the different parts of the stack. -ruby-debug creates a context when a stopping point or an event is reached. The context has information about the suspended program which enables a debugger to inspect the frame stack, evaluate variables from the perspective of the debugged program, and contains information about the place where the debugged program is stopped. +The debugger creates a context when a stopping point or an event is reached. The context has information about the suspended program which enables a debugger to inspect the frame stack, evaluate variables from the perspective of the debugged program, and contains information about the place where the debugged program is stopped. At any time you can call the +backtrace+ command (or its alias +where+) to print the backtrace of the application. This can be very helpful to know how you got where you are. If you ever wondered about how you got somewhere in your code, then +backtrace+ will supply the answer. @@ -463,7 +459,7 @@ h4. Step by Step Now you should know where you are in the running trace and be able to print the available variables. But lets continue and move on with the application execution. -Use +step+ (abbreviated +s+) to continue running your program until the next logical stopping point and return control to ruby-debug. +Use +step+ (abbreviated +s+) to continue running your program until the next logical stopping point and return control to the debugger. TIP: You can also use <tt>step<plus> n</tt> and <tt>step- n</tt> to move forward or backward +n+ steps respectively. @@ -485,12 +481,12 @@ class Author < ActiveRecord::Base end </ruby> -TIP: You can use ruby-debug while using +rails console+. Just remember to +require "ruby-debug"+ before calling the +debugger+ method. +TIP: You can use the debugger while using +rails console+. Just remember to +require "debugger"+ before calling the +debugger+ method. <shell> $ rails console Loading development environment (Rails 3.1.0) ->> require "ruby-debug" +>> require "debugger" => [] >> author = Author.first => #<Author id: 1, first_name: "Bob", last_name: "Smith", created_at: "2008-07-31 12:46:10", updated_at: "2008-07-31 12:46:10"> @@ -603,7 +599,7 @@ A simple quit tries to terminate all threads in effect. Therefore your server wi h4. Settings -There are some settings that can be configured in ruby-debug to make it easier to debug your code. Here are a few of the available options: +The +debugger+ gem can automatically show the code you're stepping through and reload it when you change it in an editor. Here are a few of the available options: * +set reload+: Reload source code when changed. * +set autolist+: Execute +list+ command on every breakpoint. @@ -612,7 +608,7 @@ There are some settings that can be configured in ruby-debug to make it easier t You can see the full list by using +help set+. Use +help set _subcommand_+ to learn about a particular +set+ command. -TIP: You can include any number of these configuration lines inside a +.rdebugrc+ file in your HOME directory. ruby-debug will read this file every time it is loaded and configure itself accordingly. +TIP: You can save these settings in an +.rdebugrc+ file in your home directory. The debugger reads these global settings when it starts. Here's a good start for an +.rdebugrc+: @@ -637,7 +633,7 @@ If a Ruby object does not go out of scope, the Ruby Garbage Collector won't swee To install it run: <shell> -$ sudo gem install bleak_house +$ gem install bleak_house </shell> Then setup your application for profiling. Then add the following at the bottom of config/environment.rb: @@ -703,11 +699,12 @@ There are some Rails plugins to help you to find errors and debug your applicati h3. References * "ruby-debug Homepage":http://www.datanoise.com/ruby-debug +* "debugger Homepage":http://github.com/cldwalker/debugger * "Article: Debugging a Rails application with ruby-debug":http://www.sitepoint.com/article/debug-rails-app-ruby-debug/ * "ruby-debug Basics screencast":http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/ -* "Ryan Bate's ruby-debug screencast":http://railscasts.com/episodes/54-debugging-with-ruby-debug -* "Ryan Bate's stack trace screencast":http://railscasts.com/episodes/24-the-stack-trace -* "Ryan Bate's logger screencast":http://railscasts.com/episodes/56-the-logger +* "Ryan Bates' debugging ruby (revised) screencast":http://railscasts.com/episodes/54-debugging-ruby-revised +* "Ryan Bates' stack trace screencast":http://railscasts.com/episodes/24-the-stack-trace +* "Ryan Bates' logger screencast":http://railscasts.com/episodes/56-the-logger * "Debugging with ruby-debug":http://bashdb.sourceforge.net/ruby-debug.html * "ruby-debug cheat sheet":http://cheat.errtheblog.com/s/rdebug/ * "Ruby on Rails Wiki: How to Configure Logging":http://wiki.rubyonrails.org/rails/pages/HowtoConfigureLogging diff --git a/guides/source/generators.textile b/guides/source/generators.textile index 920ff997ae..e9d713d91d 100644 --- a/guides/source/generators.textile +++ b/guides/source/generators.textile @@ -451,6 +451,27 @@ Adds a specified source to +Gemfile+: add_source "http://gems.github.com" </ruby> +h4. +inject_into_file+ + +Injects a block of code into a defined position in your file. + +<ruby> +inject_into_file 'name_of_file.rb', :after => "#The code goes below this line. Don't forget the Line break at the end\n" do <<-'RUBY' + puts "Hello World" +RUBY +end +</ruby> + +h4. +gsub_file+ + +Replaces text inside a file. + +<ruby> +gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code' +</ruby + +Regular Expressions can be used to make this method more precise. You can also use append_file and prepend_file in the same way to place code at the beginning and end of a file respectively. + h4. +application+ Adds a line to +config/application.rb+ directly after the application class definition. diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index f184004f80..88d5ce6d9b 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -516,7 +516,7 @@ end A couple of things to note. We use +Post.find+ to find the post we're interested in. We also use an instance variable (prefixed by +@+) to -hold our reference to the post object. We do this because Rails will pass all instance +hold a reference to the post object. We do this because Rails will pass all instance variables to the view. Now, create a new file +app/view/posts/show.html.erb+ with the following @@ -577,8 +577,8 @@ end h4. Adding links -You can now create, show, and list posts. But it's difficult to navigate -through pages, so let's add some links. +You can now create, show, and list posts. Now let's add some links to +navigate through pages. Open +app/views/welcome/index.html.erb+ and modify it as follows: @@ -619,19 +619,7 @@ Let's add links to the other views as well. # app/views/posts/new.html.erb <%= form_for :post do |f| %> - <p> - <%= f.label :title %><br> - <%= f.text_field :title %> - </p> - - <p> - <%= f.label :text %><br> - <%= f.text_area :text %> - </p> - - <p> - <%= f.submit %> - </p> + ... <% end %> <%= link_to 'Back', :action => :index %> @@ -657,11 +645,9 @@ controller by default. TIP: In development mode (which is what you're working in by default), Rails reloads your application with every browser request, so there's no need to stop -and restart the web server. - -Congratulations, you're riding the rails! Now it’s time to see how it all works. +and restart the web server when a change is made. -h4. The Model +h4. Adding Some Validation The model file, +app/models/post.rb+ is about as simple as it can get: @@ -676,8 +662,6 @@ your Rails models for free, including basic database CRUD (Create, Read, Update, Destroy) operations, data validation, as well as sophisticated search support and the ability to relate multiple models to one another. -h4. Adding Some Validation - Rails includes methods to help you validate the data that you send to models. Open the +app/models/post.rb+ file and edit it: @@ -730,7 +714,7 @@ something went wrong. To do that, you'll modify +app/views/posts/index.html.erb+ to check for error messages: <erb> -<%= form_for :post do |f| %> +<%= form_for :post, :url => { :action => :create } do |f| %> <% if @post.errors.any? %> <div id="errorExplanation"> <h2><%= pluralize(@post.errors.count, "error") %> prohibited @@ -780,6 +764,172 @@ Now you'll get a nice error message when saving a post without title: !images/getting_started/form_with_errors.png(Form With Errors)! +h4. Updating Posts + +We've covered the "CR" part of CRUD. Now let's focus on the "U" part, +updating posts. + +The first step we'll take is adding a +edit+ action to ++posts_controller+. + +Start by adding a route to +config/routes.rb+: + +<ruby> +get "posts/:id/edit" => "posts#edit" +</ruby> + +And then add the controller action: + +<ruby> +def edit + @post = Post.find(params[:id]) +end +</ruby> + +The view will contain a form similar to the one we used when creating +new posts. Create a file called +app/views/posts/edit.html.erb+ and make +it look as follows: + +<erb> +<h1>Editing post</h1> + +<%= form_for :post, :url => { :action => :update, :id => @post.id }, +:method => :put do |f| %> + <% if @post.errors.any? %> + <div id="errorExplanation"> + <h2><%= pluralize(@post.errors.count, "error") %> prohibited + this post from being saved:</h2> + <ul> + <% @post.errors.full_messages.each do |msg| %> + <li><%= msg %></li> + <% end %> + </ul> + </div> + <% end %> + <p> + <%= f.label :title %><br> + <%= f.text_field :title %> + </p> + + <p> + <%= f.label :text %><br> + <%= f.text_area :text %> + </p> + + <p> + <%= f.submit %> + </p> +<% end %> + +<%= link_to 'Back', :action => :index %> +</erb> + +This time we point the form to the +update+ action (not defined yet). +The +:method => :put+ option tells Rails that we want this form to be +submitted via +put+, which is the http method you're expected to use to +*update* resources according to the REST protocol. + +TIP: By default forms built with the +form_for_ helper are sent via +POST+. + +Moving on, we need to add the +update+ action. The file ++config/routes.rb+ will need just one more line: + +<ruby> +put "posts/:id/update" +</ruby> + +And the +update+ action in +posts_controller+ itself should not look too complicated by now: + +<ruby> +def update + @post = Post.find(params[:id]) + + if @post.update_attributes(params[:post]) + redirect_to :action => :show, :id => @post.id + else + render 'edit' + end +end +</ruby> + +The new method +update_attributes+ is used when you want to update a record +that already exists, and it accepts an hash containing the attributes +that you want to update. As before, if there was an error updating the +post we want to show the form back to the user. + +TIP: you don't need to pass all attributes to +update_attributes+. For +example, if you'd call +@post.update_attributes(:title => 'A new title')+ +Rails would only update the +title+ attribute, leaving all other +attributes untouched. + +Finally, we want to show a link to the +edit+ action in the +index+ and ++show+ views: + +<erb> +# app/view/posts/index.html.erb + +<table> + <tr> + <th>Title</th> + <th>Text</th> + <th></th> + <th></th> + </tr> + +<% @posts.each do |post| %> + <tr> + <td><%= post.title %></td> + <td><%= post.text %></td> + <td><%= link_to 'Show', :action => :show, :id => post.id %></td> + <td><%= link_to 'Edit', :action => :edit, :id => post.id %></td> + </tr> +<% end %> +</table> + +# app/view/posts/show.html.erb + +... + +<%= link_to 'Back', :action => :index %> +| <%= link_to 'Edit', :action => :edit, :id => @post.id %> +</erb> + +And here's how our app looks so far: + +!images/getting_started/index_action_with_edit_link.png(Index action +with edit link)! + +h4. Using partials to clean up duplication in views + ++partials+ are what Rails uses to remove duplication in views. Here's a +simple example: + +<erb> +# app/views/user/show.html.erb + +<h1><%= @user.name %></h1> + +<%= render 'user_details' %> + +# app/views/user/_user_details.html.erb + +<%= @user.location %> + +<%= @user.about_me %> +</erb> + +The +show+ view will automatically include the content of the ++_user_details+ view. Note that partials are prefixed by an underscore, +as to not be confused with regular views. However, you don't include the +underscore when including them with the +helper+ method. + +TIP: You can red more about partials in the "Layouts and Rendering in +Rails":layouts_and_rendering.html guide. + +Our +edit+ action looks very similar to the +new+ action, in fact they +both share the same code for displaying the form. Lets clean them up by +using a +_form+ partial. + h4. Using the Console To see your validations in action, you can use the console. The console is a diff --git a/guides/source/layout.html.erb b/guides/source/layout.html.erb index 35b6fc7014..0a8daf7ae5 100644 --- a/guides/source/layout.html.erb +++ b/guides/source/layout.html.erb @@ -14,6 +14,8 @@ <link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" /> <link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" /> + +<link href="images/favicon.ico" rel="shortcut icon" type="image/x-icon" /> </head> <body class="guide"> <% if @edge %> diff --git a/guides/source/plugins.textile b/guides/source/plugins.textile index 97b4eca779..95e38db483 100644 --- a/guides/source/plugins.textile +++ b/guides/source/plugins.textile @@ -25,16 +25,14 @@ endprologue. h3. Setup -Before you continue, take a moment to decide if your new plugin will be potentially shared across different Rails applications. +_"vendored plugins"_ were available in previous versions of Rails, but they are deprecated in +Rails 3.2, and will not be available in the future. -* If your plugin is specific to your application, your new plugin will be a _vendored plugin_. -* If you think your plugin may be used across applications, build it as a _gemified plugin_. +Currently, Rails plugins are built as gems, _gemified plugins_. They can be shared accross +different rails applications using RubyGems and Bundler if desired. h4. Generate a gemified plugin. -Writing your Rails plugin as a gem, rather than as a vendored plugin, - lets you share your plugin across different rails applications using - RubyGems and Bundler. Rails 3.1 ships with a +rails plugin new+ command which creates a skeleton for developing any kind of Rails extension with the ability diff --git a/guides/source/routing.textile b/guides/source/routing.textile index 75f4e82918..5e1cc042dc 100644 --- a/guides/source/routing.textile +++ b/guides/source/routing.textile @@ -25,7 +25,7 @@ GET /patients/17 it asks the router to match it to a controller action. If the first matching route is <ruby> -match "/patients/:id" => "patients#show" +get "/patients/:id" => "patients#show" </ruby> the request is dispatched to the +patients+ controller's +show+ action with <tt>{ :id => "17" }</tt> in +params+. @@ -121,7 +121,7 @@ h4. Singular Resources Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like +/profile+ to always show the profile of the currently logged in user. In this case, you can use a singular resource to map +/profile+ (rather than +/profile/:id+) to the +show+ action. <ruby> -match "profile" => "users#show" +get "profile" => "users#show" </ruby> This resourceful route @@ -374,7 +374,7 @@ h4. Bound Parameters When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: +:controller+ maps to the name of a controller in your application, and +:action+ maps to the name of an action within that controller. For example, consider one of the default Rails routes: <ruby> -match ':controller(/:action(/:id))' +get ':controller(/:action(/:id))' </ruby> If an incoming request of +/photos/show/1+ is processed by this route (because it hasn't matched any previous route in the file), then the result will be to invoke the +show+ action of the +PhotosController+, and to make the final parameter +"1"+ available as +params[:id]+. This route will also route the incoming request of +/photos+ to +PhotosController#index+, since +:action+ and +:id+ are optional parameters, denoted by parentheses. @@ -384,7 +384,7 @@ h4. Dynamic Segments You can set up as many dynamic segments within a regular route as you like. Anything other than +:controller+ or +:action+ will be available to the action as part of +params+. If you set up this route: <ruby> -match ':controller/:action/:id/:user_id' +get ':controller/:action/:id/:user_id' </ruby> An incoming path of +/photos/show/1/2+ will be dispatched to the +show+ action of the +PhotosController+. +params[:id]+ will be +"1"+, and +params[:user_id]+ will be +"2"+. @@ -392,7 +392,7 @@ An incoming path of +/photos/show/1/2+ will be dispatched to the +show+ action o NOTE: You can't use +:namespace+ or +:module+ with a +:controller+ path segment. If you need to do this then use a constraint on :controller that matches the namespace you require. e.g: <ruby> -match ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/ +get ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/ </ruby> TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment add a constraint which overrides this - for example +:id+ => /[^\/]+/ allows anything except a slash. @@ -402,7 +402,7 @@ h4. Static Segments You can specify static segments when creating a route: <ruby> -match ':controller/:action/:id/with_user/:user_id' +get ':controller/:action/:id/with_user/:user_id' </ruby> This route would respond to paths such as +/photos/show/1/with_user/2+. In this case, +params+ would be <tt>{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }</tt>. @@ -412,7 +412,7 @@ h4. The Query String The +params+ will also include any parameters from the query string. For example, with this route: <ruby> -match ':controller/:action/:id' +get ':controller/:action/:id' </ruby> An incoming path of +/photos/show/1?user_id=2+ will be dispatched to the +show+ action of the +Photos+ controller. +params+ will be <tt>{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }</tt>. @@ -422,7 +422,7 @@ h4. Defining Defaults You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply them as defaults: <ruby> -match 'photos/:id' => 'photos#show' +get 'photos/:id' => 'photos#show' </ruby> With this route, Rails will match an incoming path of +/photos/12+ to the +show+ action of +PhotosController+. @@ -430,7 +430,7 @@ With this route, Rails will match an incoming path of +/photos/12+ to the +show+ You can also define other defaults in a route by supplying a hash for the +:defaults+ option. This even applies to parameters that you do not specify as dynamic segments. For example: <ruby> -match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } +get 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } </ruby> Rails would match +photos/12+ to the +show+ action of +PhotosController+, and set +params[:format]+ to +"jpg"+. @@ -440,49 +440,45 @@ h4. Naming Routes You can specify a name for any route using the +:as+ option. <ruby> -match 'exit' => 'sessions#destroy', :as => :logout +get 'exit' => 'sessions#destroy', :as => :logout </ruby> This will create +logout_path+ and +logout_url+ as named helpers in your application. Calling +logout_path+ will return +/exit+ h4. HTTP Verb Constraints -You can use the +:via+ option to constrain the request to one or more HTTP methods: +In general, you should use the +get+, +post+, +put+ and +delete+ methods to constrain a route to a particular verb. You can use the +match+ method with the +:via+ option to match multiple verbs at once: <ruby> -match 'photos/show' => 'photos#show', :via => :get +match 'photos' => 'photos#show', :via => [:get, :post] </ruby> -There is a shorthand version of this as well: +You can match all verbs to a particular route using +:via => :all+: <ruby> -get 'photos/show' +match 'photos' => 'photos#show', :via => :all </ruby> -You can also permit more than one verb to a single route: - -<ruby> -match 'photos/show' => 'photos#show', :via => [:get, :post] -</ruby> +You should avoid routing all verbs to an action unless you have a good reason to, as routing both +GET+ requests and +POST+ requests to a single action has security implications. h4. Segment Constraints You can use the +:constraints+ option to enforce a format for a dynamic segment: <ruby> -match 'photos/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ } +get 'photos/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ } </ruby> This route would match paths such as +/photos/A12345+. You can more succinctly express the same route this way: <ruby> -match 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ +get 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ </ruby> +:constraints+ takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work: <ruby> -match '/:id' => 'posts#show', :constraints => {:id => /^\d/} +get '/:id' => 'posts#show', :constraints => {:id => /^\d/} </ruby> However, note that you don't need to use anchors because all routes are anchored at the start. @@ -490,8 +486,8 @@ However, note that you don't need to use anchors because all routes are anchored For example, the following routes would allow for +posts+ with +to_param+ values like +1-hello-world+ that always begin with a number and +users+ with +to_param+ values like +david+ that never begin with a number to share the root namespace: <ruby> -match '/:id' => 'posts#show', :constraints => { :id => /\d.+/ } -match '/:username' => 'users#show' +get '/:id' => 'posts#show', :constraints => { :id => /\d.+/ } +get '/:username' => 'users#show' </ruby> h4. Request-Based Constraints @@ -501,7 +497,7 @@ You can also constrain a route based on any method on the <a href="action_contro You specify a request-based constraint the same way that you specify a segment constraint: <ruby> -match "photos", :constraints => {:subdomain => "admin"} +get "photos", :constraints => {:subdomain => "admin"} </ruby> You can also specify constraints in a block form: @@ -530,7 +526,7 @@ class BlacklistConstraint end TwitterClone::Application.routes.draw do - match "*path" => "blacklist#index", + get "*path" => "blacklist#index", :constraints => BlacklistConstraint.new end </ruby> @@ -539,7 +535,7 @@ You can also specify constraints as a lambda: <ruby> TwitterClone::Application.routes.draw do - match "*path" => "blacklist#index", + get "*path" => "blacklist#index", :constraints => lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) } end </ruby> @@ -551,7 +547,7 @@ h4. Route Globbing Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example <ruby> -match 'photos/*other' => 'photos#unknown' +get 'photos/*other' => 'photos#unknown' </ruby> This route would match +photos/12+ or +/photos/long/path/to/12+, setting +params[:other]+ to +"12"+ or +"long/path/to/12"+. @@ -559,7 +555,7 @@ This route would match +photos/12+ or +/photos/long/path/to/12+, setting +params Wildcard segments can occur anywhere in a route. For example, <ruby> -match 'books/*section/:title' => 'books#show' +get 'books/*section/:title' => 'books#show' </ruby> would match +books/some/section/last-words-a-memoir+ with +params[:section]+ equals +"some/section"+, and +params[:title]+ equals +"last-words-a-memoir"+. @@ -567,7 +563,7 @@ would match +books/some/section/last-words-a-memoir+ with +params[:section]+ equ Technically a route can have even more than one wildcard segment. The matcher assigns segments to parameters in an intuitive way. For example, <ruby> -match '*a/foo/*b' => 'test#index' +get '*a/foo/*b' => 'test#index' </ruby> would match +zoo/woo/foo/bar/baz+ with +params[:a]+ equals +"zoo/woo"+, and +params[:b]+ equals +"bar/baz"+. @@ -575,19 +571,19 @@ would match +zoo/woo/foo/bar/baz+ with +params[:a]+ equals +"zoo/woo"+, and +par NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route: <ruby> -match '*pages' => 'pages#show' +get '*pages' => 'pages#show' </ruby> NOTE: By requesting +"/foo/bar.json"+, your +params[:pages]+ will be equals to +"foo/bar"+ with the request format of JSON. If you want the old 3.0.x behavior back, you could supply +:format => false+ like this: <ruby> -match '*pages' => 'pages#show', :format => false +get '*pages' => 'pages#show', :format => false </ruby> NOTE: If you want to make the format segment mandatory, so it cannot be omitted, you can supply +:format => true+ like this: <ruby> -match '*pages' => 'pages#show', :format => true +get '*pages' => 'pages#show', :format => true </ruby> h4. Redirection @@ -595,20 +591,20 @@ h4. Redirection You can redirect any path to another path using the +redirect+ helper in your router: <ruby> -match "/stories" => redirect("/posts") +get "/stories" => redirect("/posts") </ruby> You can also reuse dynamic segments from the match in the path to redirect to: <ruby> -match "/stories/:name" => redirect("/posts/%{name}") +get "/stories/:name" => redirect("/posts/%{name}") </ruby> You can also provide a block to redirect, which receives the params and (optionally) the request object: <ruby> -match "/stories/:name" => redirect {|params| "/posts/#{params[:name].pluralize}" } -match "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" } +get "/stories/:name" => redirect {|params| "/posts/#{params[:name].pluralize}" } +get "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" } </ruby> Please note that this redirection is a 301 "Moved Permanently" redirect. Keep in mind that some web browsers or proxy servers will cache this type of redirect, making the old page inaccessible. @@ -620,10 +616,10 @@ h4. Routing to Rack Applications Instead of a String, like +"posts#index"+, which corresponds to the +index+ action in the +PostsController+, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher. <ruby> -match "/application.js" => Sprockets +match "/application.js" => Sprockets, :via => :all </ruby> -As long as +Sprockets+ responds to +call+ and returns a <tt>[status, headers, body]</tt>, the router won't know the difference between the Rack application and an action. +As long as +Sprockets+ responds to +call+ and returns a <tt>[status, headers, body]</tt>, the router won't know the difference between the Rack application and an action. This is an appropriate use of +:via => :all+, as you will want to allow your Rack application to handle all verbs as it considers appropriate. NOTE: For the curious, +"posts#index"+ actually expands out to +PostsController.action(:index)+, which returns a valid Rack application. @@ -638,6 +634,8 @@ root 'pages#main' # shortcut for the above You should put the +root+ route at the top of the file, because it is the most popular route and should be matched first. You also need to delete the +public/index.html+ file for the root route to take effect. +NOTE: The +root+ route only routes +GET+ requests to the action. + h3. Customizing Resourceful Routes While the default routes and helpers generated by +resources :posts+ will usually serve you well, you may want to customize them in some way. Rails allows you to customize virtually any generic part of the resourceful helpers. diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 7da495211d..002c6026e4 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -22,7 +22,7 @@ module Rails initializer :add_builtin_route do |app| if Rails.env.development? app.routes.append do - match '/rails/info/properties' => "rails/info#properties" + get '/rails/info/properties' => "rails/info#properties" end end end diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console.rb index d7c9e820dc..cd6a03fe51 100644 --- a/railties/lib/rails/commands/console.rb +++ b/railties/lib/rails/commands/console.rb @@ -27,7 +27,7 @@ module Rails opt.on("-e", "--environment=name", String, "Specifies the environment to run this console under (test/development/production).", "Default: development") { |v| options[:environment] = v.strip } - opt.on("--debugger", 'Enable ruby-debugging for the console.') { |v| options[:debugger] = v } + opt.on("--debugger", 'Enable the debugger.') { |v| options[:debugger] = v } opt.parse!(arguments) end @@ -73,10 +73,10 @@ module Rails def require_debugger begin - require 'ruby-debug' + require 'debugger' puts "=> Debugger enabled" rescue Exception - puts "You need to install ruby-debug19 to run the console in debugging mode. With gems, use 'gem install ruby-debug19'" + puts "You're missing the 'debugger' gem. Add it to your Gemfile, bundle, and try again." exit end end diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 721a47a974..4c4caad69f 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -17,7 +17,7 @@ module Rails opts.on("-c", "--config=file", String, "Use custom rackup configuration file") { |v| options[:config] = v } opts.on("-d", "--daemon", "Make server run as a Daemon.") { options[:daemonize] = true } - opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { options[:debugger] = true } + opts.on("-u", "--debugger", "Enable the debugger") { options[:debugger] = true } opts.on("-e", "--environment=name", String, "Specifies the environment to run this server under (test/development/production).", "Default: development") { |v| options[:environment] = v } diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 131d6e5711..43ee396cbe 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -148,7 +148,7 @@ module Rails # # # ENGINE/config/routes.rb # MyEngine::Engine.routes.draw do - # match "/" => "posts#index" + # get "/" => "posts#index" # end # # == Mount priority @@ -158,7 +158,7 @@ module Rails # # MyRailsApp::Application.routes.draw do # mount MyEngine::Engine => "/blog" - # match "/blog/omg" => "main#omg" + # get "/blog/omg" => "main#omg" # end # # +MyEngine+ is mounted at <tt>/blog</tt>, and <tt>/blog/omg</tt> points to application's @@ -167,7 +167,7 @@ module Rails # It's much better to swap that: # # MyRailsApp::Application.routes.draw do - # match "/blog/omg" => "main#omg" + # get "/blog/omg" => "main#omg" # mount MyEngine::Engine => "/blog" # end # @@ -256,7 +256,7 @@ module Rails # # config/routes.rb # MyApplication::Application.routes.draw do # mount MyEngine::Engine => "/my_engine", :as => "my_engine" - # match "/foo" => "foo#index" + # get "/foo" => "foo#index" # end # # Now, you can use the <tt>my_engine</tt> helper inside your application: diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index c457b5fbbc..e85d1b8fa2 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -40,7 +40,7 @@ module Rails def indent(content, multiplier = 2) spaces = " " * multiplier - content = content.each_line.map {|line| "#{spaces}#{line}" }.join + content = content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join end def wrap_with_namespace(content) diff --git a/railties/lib/rails/generators/rails/app/templates/README b/railties/lib/rails/generators/rails/app/templates/README index d2014bd35f..b5d7b6436b 100644 --- a/railties/lib/rails/generators/rails/app/templates/README +++ b/railties/lib/rails/generators/rails/app/templates/README @@ -86,8 +86,8 @@ programming in general. Debugger support is available through the debugger command when you start your Mongrel or WEBrick server with --debugger. This means that you can break out of execution at any point in the code, investigate and change the model, and then, -resume execution! You need to install ruby-debug19 to run the server in debugging -mode. With gems, use <tt>sudo gem install ruby-debug19</tt>. Example: +resume execution! You need to install the 'debugger' gem to run the server in debugging +mode. Add gem 'debugger' to your Gemfile and run <tt>bundle</tt> to install it. Example: class WeblogController < ActionController::Base def index diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb index 24026cf324..286e93c3cf 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb @@ -51,5 +51,4 @@ # root :to => 'welcome#index' # See how all your routes lay out with "rake routes" - -end +end
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile index d316b00c43..9399c9cb77 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile @@ -20,4 +20,4 @@ gem "jquery-rails" <% end -%> # To use debugger -# gem 'ruby-debug19', :require => 'ruby-debug' +# gem 'debugger' diff --git a/railties/lib/rails/rack/debugger.rb b/railties/lib/rails/rack/debugger.rb index 5a78da1731..902361ce77 100644 --- a/railties/lib/rails/rack/debugger.rb +++ b/railties/lib/rails/rack/debugger.rb @@ -6,13 +6,13 @@ module Rails ARGV.clear # clear ARGV so that rails server options aren't passed to IRB - require 'ruby-debug' + require 'debugger' ::Debugger.start ::Debugger.settings[:autoeval] = true if ::Debugger.respond_to?(:settings) puts "=> Debugger enabled" rescue LoadError - puts "You need to install ruby-debug19 to run the server in debugging mode. With gems, use 'gem install ruby-debug19'" + puts "You're missing the 'debugger' gem. Add it to your Gemfile, bundle, and try again." exit end diff --git a/railties/test/application/asset_debugging_test.rb b/railties/test/application/asset_debugging_test.rb index 1ac349a560..ecacb34cb2 100644 --- a/railties/test/application/asset_debugging_test.rb +++ b/railties/test/application/asset_debugging_test.rb @@ -15,7 +15,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index 37981917e3..e23a19d69c 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -28,7 +28,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '*path', :to => lambda { |env| [200, { "Content-Type" => "text/html" }, "Not an asset"] } + get '*path', :to => lambda { |env| [200, { "Content-Type" => "text/html" }, "Not an asset"] } end RUBY @@ -204,7 +204,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY @@ -230,7 +230,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY @@ -334,7 +334,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/omg', :to => "omg#index" + get '/omg', :to => "omg#index" end RUBY @@ -513,7 +513,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY end diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index a08e5b2374..c2d4a0f2c8 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -116,7 +116,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match "/:controller(/:action)" + get "/:controller(/:action)" end RUBY diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb index abb277dc1d..02d20bc150 100644 --- a/railties/test/application/initializers/i18n_test.rb +++ b/railties/test/application/initializers/i18n_test.rb @@ -85,7 +85,7 @@ en: app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/i18n', :to => lambda { |env| [200, {}, [Foo.instance_variable_get('@foo')]] } + get '/i18n', :to => lambda { |env| [200, {}, [Foo.instance_variable_get('@foo')]] } end RUBY @@ -109,7 +109,7 @@ en: app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/i18n', :to => lambda { |env| [200, {}, [I18n.t(:foo)]] } + get '/i18n', :to => lambda { |env| [200, {}, [I18n.t(:foo)]] } end RUBY diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb index 92951e1676..e0286502f3 100644 --- a/railties/test/application/loading_test.rb +++ b/railties/test/application/loading_test.rb @@ -77,8 +77,8 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/load', :to => lambda { |env| [200, {}, Post.all] } - match '/unload', :to => lambda { |env| [200, {}, []] } + get '/load', :to => lambda { |env| [200, {}, Post.all] } + get '/unload', :to => lambda { |env| [200, {}, []] } end RUBY @@ -107,7 +107,7 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } + get '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } end RUBY @@ -146,7 +146,7 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } + get '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } end RUBY @@ -182,7 +182,7 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY $counter = 0 AppTemplate::Application.routes.draw do - match '/c', :to => lambda { |env| User; [200, {"Content-Type" => "text/plain"}, [$counter.to_s]] } + get '/c', :to => lambda { |env| User; [200, {"Content-Type" => "text/plain"}, [$counter.to_s]] } end RUBY @@ -213,8 +213,8 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/title', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.title]] } - match '/body', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.body]] } + get '/title', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.title]] } + get '/body', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.body]] } end RUBY @@ -272,7 +272,7 @@ class LoadingTest < ActiveSupport::TestCase app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match "/:controller(/:action)" + get "/:controller(/:action)" end RUBY diff --git a/railties/test/application/middleware/cache_test.rb b/railties/test/application/middleware/cache_test.rb index 561b020707..54b18542c2 100644 --- a/railties/test/application/middleware/cache_test.rb +++ b/railties/test/application/middleware/cache_test.rb @@ -46,7 +46,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY end diff --git a/railties/test/application/middleware/exceptions_test.rb b/railties/test/application/middleware/exceptions_test.rb index c5048afa13..d1a614e181 100644 --- a/railties/test/application/middleware/exceptions_test.rb +++ b/railties/test/application/middleware/exceptions_test.rb @@ -105,7 +105,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + post ':controller(/:action)' end RUBY diff --git a/railties/test/application/route_inspect_test.rb b/railties/test/application/route_inspect_test.rb index 6393cfff4b..59dfe2ff75 100644 --- a/railties/test/application/route_inspect_test.rb +++ b/railties/test/application/route_inspect_test.rb @@ -78,47 +78,47 @@ module ApplicationTests root :to => 'pages#main' end output = @inspector.format @set.routes - assert_equal ["root / pages#main"], output + assert_equal ["root GET / pages#main"], output end def test_inspect_routes_shows_dynamic_action_route @set.draw do - match 'api/:action' => 'api' + get 'api/:action' => 'api' end output = @inspector.format @set.routes - assert_equal [" /api/:action(.:format) api#:action"], output + assert_equal [" GET /api/:action(.:format) api#:action"], output end def test_inspect_routes_shows_controller_and_action_only_route @set.draw do - match ':controller/:action' + get ':controller/:action' end output = @inspector.format @set.routes - assert_equal [" /:controller/:action(.:format) :controller#:action"], output + assert_equal [" GET /:controller/:action(.:format) :controller#:action"], output end def test_inspect_routes_shows_controller_and_action_route_with_constraints @set.draw do - match ':controller(/:action(/:id))', :id => /\d+/ + get ':controller(/:action(/:id))', :id => /\d+/ end output = @inspector.format @set.routes - assert_equal [" /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"], output + assert_equal [" GET /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"], output end def test_rake_routes_shows_route_with_defaults @set.draw do - match 'photos/:id' => 'photos#show', :defaults => {:format => 'jpg'} + get 'photos/:id' => 'photos#show', :defaults => {:format => 'jpg'} end output = @inspector.format @set.routes - assert_equal [%Q[ /photos/:id(.:format) photos#show {:format=>"jpg"}]], output + assert_equal [%Q[ GET /photos/:id(.:format) photos#show {:format=>"jpg"}]], output end def test_rake_routes_shows_route_with_constraints @set.draw do - match 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ + get 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ end output = @inspector.format @set.routes - assert_equal [" /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}"], output + assert_equal [" GET /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}"], output end class RackApp @@ -128,10 +128,10 @@ module ApplicationTests def test_rake_routes_shows_route_with_rack_app @set.draw do - match 'foo/:id' => RackApp, :id => /[A-Z]\d{5}/ + get 'foo/:id' => RackApp, :id => /[A-Z]\d{5}/ end output = @inspector.format @set.routes - assert_equal [" /foo/:id(.:format) #{RackApp.name} {:id=>/[A-Z]\\d{5}/}"], output + assert_equal [" GET /foo/:id(.:format) #{RackApp.name} {:id=>/[A-Z]\\d{5}/}"], output end def test_rake_routes_shows_route_with_rack_app_nested_with_dynamic_constraints @@ -153,7 +153,7 @@ module ApplicationTests def test_rake_routes_dont_show_app_mounted_in_assets_prefix @set.draw do - match '/sprockets' => RackApp + get '/sprockets' => RackApp end output = @inspector.format @set.routes assert_no_match(/RackApp/, output.first) diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index 28ce3beea9..204f43a442 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -53,7 +53,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY @@ -94,7 +94,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY @@ -126,8 +126,8 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'admin/foo', :to => 'admin/foo#index' - match 'foo', :to => 'foo#index' + get 'admin/foo', :to => 'admin/foo#index' + get 'foo', :to => 'foo#index' end RUBY @@ -141,13 +141,13 @@ module ApplicationTests test "routes appending blocks" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller/:action' + get ':controller/:action' end RUBY add_to_config <<-R routes.append do - match '/win' => lambda { |e| [200, {'Content-Type'=>'text/plain'}, ['WIN']] } + get '/win' => lambda { |e| [200, {'Content-Type'=>'text/plain'}, ['WIN']] } end R @@ -158,7 +158,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-R AppTemplate::Application.routes.draw do - match 'lol' => 'hello#index' + get 'lol' => 'hello#index' end R @@ -182,7 +182,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => 'foo#bar' + get 'foo', :to => 'foo#bar' end RUBY @@ -193,7 +193,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => 'foo#baz' + get 'foo', :to => 'foo#baz' end RUBY @@ -214,7 +214,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => ::InitializeRackApp + get 'foo', :to => ::InitializeRackApp end RUBY diff --git a/railties/test/application/url_generation_test.rb b/railties/test/application/url_generation_test.rb index 85a8a15fcc..f7e60749a7 100644 --- a/railties/test/application/url_generation_test.rb +++ b/railties/test/application/url_generation_test.rb @@ -31,7 +31,7 @@ module ApplicationTests end MyApp.routes.draw do - match "/" => "omg#index", :as => :omg + get "/" => "omg#index", :as => :omg end require 'rack/test' diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index 5c63b13dce..abafcefde5 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -56,11 +56,19 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase run_generator assert_file "config/routes.rb", /get "account\/foo"/, /get "account\/bar"/ end -# + def test_invokes_default_template_engine_even_with_no_action run_generator ["account"] assert_file "app/views/test_app/account" end + + def test_namespaced_controller_dont_indent_blank_lines + run_generator + assert_file "app/controllers/test_app/account_controller.rb" + File.readlines(File.expand_path("app/controllers/test_app/account_controller.rb", destination_root)).each do |line| + assert_no_match line.chomp, /^\s+$/, "Don't indent blank lines" + end + end end class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index ac4c2abfc8..b28cc6e04d 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -112,7 +112,7 @@ module TestHelpers routes = File.read("#{app_path}/config/routes.rb") if routes =~ /(\n\s*end\s*)\Z/ File.open("#{app_path}/config/routes.rb", 'w') do |f| - f.puts $` + "\nmatch ':controller(/:action(/:id))(.:format)'\n" + $1 + f.puts $` + "\nmatch ':controller(/:action(/:id))(.:format)', :via => :all\n" + $1 end end @@ -143,7 +143,7 @@ module TestHelpers app.initialize! app.routes.draw do - match "/" => "omg#index" + get "/" => "omg#index" end require 'rack/test' @@ -161,7 +161,7 @@ module TestHelpers app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY end diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb index 8a9363fb80..f7a30a16d2 100644 --- a/railties/test/rails_info_controller_test.rb +++ b/railties/test/rails_info_controller_test.rb @@ -11,7 +11,7 @@ class InfoControllerTest < ActionController::TestCase def setup Rails.application.routes.draw do - match '/rails/info/properties' => "rails/info#properties" + get '/rails/info/properties' => "rails/info#properties" end @request.stubs(:local? => true) @controller.stubs(:consider_all_requests_local? => false) diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 5e93a8e783..beae2c5f2c 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -218,7 +218,7 @@ module RailtiesTest end Rails.application.routes.draw do - match "/sprokkit", :to => Sprokkit + get "/sprokkit", :to => Sprokkit end RUBY @@ -241,7 +241,7 @@ module RailtiesTest app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => 'foo#index' + get 'foo', :to => 'foo#index' end RUBY @@ -255,8 +255,8 @@ module RailtiesTest @plugin.write "config/routes.rb", <<-RUBY Rails.application.routes.draw do - match 'foo', :to => 'bar#index' - match 'bar', :to => 'bar#index' + get 'foo', :to => 'bar#index' + get 'bar', :to => 'bar#index' end RUBY @@ -336,7 +336,7 @@ YAML Rails.application.routes.draw do namespace :admin do namespace :foo do - match "bar", :to => "bar#index" + get "bar", :to => "bar#index" end end end @@ -491,7 +491,7 @@ YAML @plugin.write "config/routes.rb", <<-RUBY Bukkits::Engine.routes.draw do - match "/foo" => lambda { |env| [200, {'Content-Type' => 'text/html'}, ['foo']] } + get "/foo" => lambda { |env| [200, {'Content-Type' => 'text/html'}, ['foo']] } end RUBY @@ -570,18 +570,18 @@ YAML app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match "/bar" => "bar#index", :as => "bar" + get "/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" => "foo#index", :as => "foo" - match "/foo/show" => "foo#show" - match "/from_app" => "foo#from_app" - match "/routes_helpers_in_view" => "foo#routes_helpers_in_view" - match "/polymorphic_path_without_namespace" => "foo#polymorphic_path_without_namespace" + get "/foo" => "foo#index", :as => "foo" + get "/foo/show" => "foo#show" + get "/from_app" => "foo#from_app" + get "/routes_helpers_in_view" => "foo#routes_helpers_in_view" + get "/polymorphic_path_without_namespace" => "foo#polymorphic_path_without_namespace" resources :posts end RUBY @@ -738,7 +738,7 @@ YAML @plugin.write "config/routes.rb", <<-RUBY Bukkits::Awesome::Engine.routes.draw do - match "/foo" => "foo#index" + get "/foo" => "foo#index" end RUBY @@ -1008,8 +1008,8 @@ YAML app_file "config/routes.rb", <<-RUBY Rails.application.routes.draw do - match "/foo" => "main#foo" - match "/bar" => "main#bar" + get "/foo" => "main#foo" + get "/bar" => "main#bar" end RUBY @@ -1080,7 +1080,7 @@ YAML app_file "config/routes.rb", <<-RUBY Rails.application.routes.draw do - match "/foo" => "main#foo" + get "/foo" => "main#foo" end RUBY diff --git a/railties/test/railties/mounted_engine_test.rb b/railties/test/railties/mounted_engine_test.rb index 2bb9df6b64..4c0fdee556 100644 --- a/railties/test/railties/mounted_engine_test.rb +++ b/railties/test/railties/mounted_engine_test.rb @@ -18,13 +18,13 @@ module ApplicationTests AppTemplate::Application.routes.draw do mount Weblog::Engine, :at => '/', :as => 'weblog' resources :posts - match "/engine_route" => "application_generating#engine_route" - match "/engine_route_in_view" => "application_generating#engine_route_in_view" - match "/weblog_engine_route" => "application_generating#weblog_engine_route" - match "/weblog_engine_route_in_view" => "application_generating#weblog_engine_route_in_view" - match "/url_for_engine_route" => "application_generating#url_for_engine_route" - match "/polymorphic_route" => "application_generating#polymorphic_route" - match "/application_polymorphic_path" => "application_generating#application_polymorphic_path" + get "/engine_route" => "application_generating#engine_route" + get "/engine_route_in_view" => "application_generating#engine_route_in_view" + get "/weblog_engine_route" => "application_generating#weblog_engine_route" + get "/weblog_engine_route_in_view" => "application_generating#weblog_engine_route_in_view" + get "/url_for_engine_route" => "application_generating#url_for_engine_route" + get "/polymorphic_route" => "application_generating#polymorphic_route" + get "/application_polymorphic_path" => "application_generating#application_polymorphic_path" scope "/:user", :user => "anonymous" do mount Blog::Engine => "/blog" end @@ -42,7 +42,7 @@ module ApplicationTests @simple_plugin.write "config/routes.rb", <<-RUBY Weblog::Engine.routes.draw do - match '/weblog' => "weblogs#index", :as => 'weblogs' + get '/weblog' => "weblogs#index", :as => 'weblogs' end RUBY @@ -86,9 +86,9 @@ module ApplicationTests @plugin.write "config/routes.rb", <<-RUBY Blog::Engine.routes.draw do resources :posts - match '/generate_application_route', :to => 'posts#generate_application_route' - match '/application_route_in_view', :to => 'posts#application_route_in_view' - match '/engine_polymorphic_path', :to => 'posts#engine_polymorphic_path' + get '/generate_application_route', :to => 'posts#generate_application_route' + get '/application_route_in_view', :to => 'posts#application_route_in_view' + get '/engine_polymorphic_path', :to => 'posts#engine_polymorphic_path' end RUBY |