diff options
169 files changed, 1612 insertions, 1356 deletions
@@ -29,7 +29,7 @@ end gem 'uglifier', '>= 1.0.3', :require => false gem 'rake', '>= 0.8.7' -gem 'mocha', '>= 0.9.8' +gem 'mocha', '>= 0.11.2' group :doc do # The current sdoc cannot generate GitHub links due diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index be7b82eecc..a33d6e072b 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,4 +1,4 @@ -## Rails 3.2.3 (unreleased) ## +## Rails 3.2.3 (March 30, 2012) ## * Upgrade mail version to 2.4.3 *ML* 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/CHANGELOG.md b/actionpack/CHANGELOG.md index 32630e5ded..b3d6ae0ac7 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -135,7 +135,7 @@ HTML5 `mark` element. *Brian Cardarella* -## Rails 3.2.3 (unreleased) ## +## Rails 3.2.3 (March 30, 2012) ## * Add `config.action_view.embed_authenticity_token_in_remote_forms` (defaults to true) which allows to set if authenticity token will be included by default in remote forms. If you change it to false, you can still force authenticity token by passing `:authenticity_token => true` in form options *Piotr Sarnacki* diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb index e9b50ff8ce..114b0e73c9 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb @@ -99,7 +99,7 @@ module HTML self.allowed_protocols = Set.new(%w(ed2k ftp http https irc mailto news gopher nntp telnet webcal xmpp callto feed svn urn aim rsync tag ssh sftp rtsp afs)) - # Specifies the default Set of acceptable css keywords that #sanitize and #sanitize_css will accept. + # Specifies the default Set of acceptable css properties that #sanitize and #sanitize_css will accept. self.allowed_css_properties = Set.new(%w(azimuth background-color border-bottom-color border-collapse border-color border-left-color border-right-color border-top-color clear color cursor direction display elevation float font font-family font-size font-style font-variant font-weight height letter-spacing line-height diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index 5c48a60469..e31f3b823d 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/module/attribute_accessors' + module ActionDispatch module Http module MimeNegotiation diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 078229efd2..cc46f9983c 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -29,7 +29,7 @@ module ActionDispatch # :nodoc: # class DemoControllerTest < ActionDispatch::IntegrationTest # def test_print_root_path_to_console # get('/') - # puts @response.body + # puts response.body # end # end class Response diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index f9dae5dad7..aaa2223d9e 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -23,22 +23,6 @@ module ActionDispatch end def url_for(options = {}) - if options[:host].blank? && options[:only_path].blank? - raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' - end - - rewritten_url = "" - - unless options[:only_path] - unless options[:protocol] == false - rewritten_url << (options[:protocol] || "http") - rewritten_url << ":" unless rewritten_url.match(%r{:|//}) - end - rewritten_url << "//" unless rewritten_url.match("//") - rewritten_url << rewrite_authentication(options) - rewritten_url << host_or_subdomain_and_domain(options) - rewritten_url << ":#{options.delete(:port)}" if options[:port] - end path = "" path << options.delete(:script_name).to_s.chomp("/") @@ -47,14 +31,36 @@ module ActionDispatch params = options[:params] || {} params.reject! {|k,v| v.to_param.nil? } - rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) - rewritten_url << "?#{params.to_query}" unless params.empty? - rewritten_url << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor] - rewritten_url + result = build_host_url(options) + + result << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) + result << "?#{params.to_query}" unless params.empty? + result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor] + result end private + def build_host_url(options) + if options[:host].blank? && options[:only_path].blank? + raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' + end + + result = "" + + unless options[:only_path] + unless options[:protocol] == false + result << (options[:protocol] || "http") + result << ":" unless result.match(%r{:|//}) + end + result << "//" unless result.match("//") + result << rewrite_authentication(options) + result << host_or_subdomain_and_domain(options) + result << ":#{options.delete(:port)}" if options[:port] + end + result + end + def named_host?(host) host && IP_HOST_REGEXP !~ host end diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index cff0877030..c92c91df65 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -17,7 +17,7 @@ module ActionDispatch # def create # # save post # flash[:notice] = "Post successfully created" - # redirect_to posts_path(@post) + # redirect_to @post # end # # def show diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 28e8fbdab8..12bc438be3 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -110,7 +110,7 @@ module ActionDispatch def build(app = nil, &block) app ||= block raise "MiddlewareStack#build requires an app" unless app - middlewares.reverse.inject(app) { |a, e| e.build(a) } + middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) } end protected diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index ba4cfb482d..fdc0bfb686 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/enumerable' require 'active_support/inflector' @@ -58,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 @@ -263,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 @@ -416,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_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index 617b24b46a..ae01781013 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -67,10 +67,13 @@ module ActionDispatch # params, depending of how many arguments your block accepts. A string is required as a # return value. # - # match 'jokes/:number', :to => redirect do |params, request| - # path = (params[:number].to_i.even? ? "/wheres-the-beef" : "/i-love-lamp") + # match 'jokes/:number', :to => redirect { |params, request| + # path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp") # "http://#{request.host_with_port}/#{path}" - # end + # } + # + # Note that the +do end+ syntax for the redirect block wouldn't work, as Ruby would pass + # the block to +match+ instead of +redirect+. Use <tt>{ ... }</tt> instead. # # The options version of redirect allows you to supply only the parts of the url which need # to change, it also supports interpolation of the path similar to the first example. diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 45075050eb..f1aa131cbb 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -96,7 +96,25 @@ module ActionDispatch def initialize @routes = {} @helpers = [] - @module = Module.new + @module = Module.new do + protected + + def handle_positional_args(args, options, route) + inner_options = args.extract_options! + result = options.dup + + if args.any? + keys = route.segment_keys + if args.size < keys.size - 1 # take format into account + keys -= self.url_options.keys if self.respond_to?(:url_options) + keys -= options.keys + end + result.merge!(Hash[keys.zip(args)]) + end + + result.merge!(inner_options) + end + end end def helper_names @@ -135,40 +153,37 @@ module ActionDispatch end private - def url_helper_name(name, kind = :url) - :"#{name}_#{kind}" + def url_helper_name(name, only_path) + if only_path + :"#{name}_path" + else + :"#{name}_url" + end end - def hash_access_name(name, kind = :url) - :"hash_for_#{name}_#{kind}" + def hash_access_name(name, only_path) + if only_path + :"hash_for_#{name}_path" + else + :"hash_for_#{name}_url" + end end def define_named_route_methods(name, route) - {:url => {:only_path => false}, :path => {:only_path => true}}.each do |kind, opts| - hash = route.defaults.merge(:use_route => name).merge(opts) - define_hash_access route, name, kind, hash - define_url_helper route, name, kind, hash + [true, false].each do |only_path| + hash = route.defaults.merge(:use_route => name, :only_path => only_path) + define_hash_access route, name, hash + define_url_helper route, name, hash end end - def define_hash_access(route, name, kind, options) - selector = hash_access_name(name, kind) + def define_hash_access(route, name, options) + selector = hash_access_name(name, options[:only_path]) @module.module_eval do - remove_possible_method selector - - define_method(selector) do |*args| - inner_options = args.extract_options! - result = options.dup - - if args.any? - result[:_positional_args] = args - result[:_positional_keys] = route.segment_keys - end - - result.merge(inner_options) + redefine_method(selector) do |*args| + self.handle_positional_args(args, options, route) end - protected selector end helpers << selector @@ -187,9 +202,9 @@ module ActionDispatch # # foo_url(bar, baz, bang, :sort_by => 'baz') # - def define_url_helper(route, name, kind, options) - selector = url_helper_name(name, kind) - hash_access_method = hash_access_name(name, kind) + def define_url_helper(route, name, options) + selector = url_helper_name(name, options[:only_path]) + hash_access_method = hash_access_name(name, options[:only_path]) if optimize_helper?(route) @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 @@ -609,8 +624,6 @@ module ActionDispatch def url_for(options) options = default_url_options.merge(options || {}) - handle_positional_args(options) - user, password = extract_authentication(options) path_segments = options.delete(:_path_segments) script_name = options.delete(:script_name).presence || _generate_prefix(options) @@ -680,16 +693,6 @@ module ActionDispatch end end - def handle_positional_args(options) - return unless args = options.delete(:_positional_args) - - keys = options.delete(:_positional_keys) - keys -= options.keys if args.size < keys.size - 1 # take format into account - - # Tell url_for to skip default_url_options - options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }]) - end - end end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index d4d09e2ee9..7985683a72 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -442,7 +442,7 @@ module ActionView # <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video> # video_tag(["trailer.ogg", "trailer.flv"]) # => # <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video> - # video_tag(["trailer.ogg", "trailer.flv"] :size => "160x120") # => + # video_tag(["trailer.ogg", "trailer.flv"], :size => "160x120") # => # <video height="120" width="160"><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video> def video_tag(*sources) multiple_sources_tag('video', sources) do |options| diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 1f237cd013..ffb1afa089 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -67,8 +67,9 @@ module ActionView 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) - distance_in_minutes = (((to_time - from_time).abs)/60).round - distance_in_seconds = ((to_time - from_time).abs).round + from_time, to_time = to_time, from_time if from_time > to_time + distance_in_minutes = ((to_time - from_time)/60.0).round + distance_in_seconds = (to_time - from_time).round I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale| case distance_in_minutes @@ -94,18 +95,22 @@ module ActionView when 43200..86399 then locale.t :about_x_months, :count => 1 when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round else - fyear = from_time.year - fyear += 1 if from_time.month >= 3 - tyear = to_time.year - tyear -= 1 if to_time.month < 3 - leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)} - minute_offset_for_leap_year = leap_years * 1440 - # Discount the leap year days when calculating year distance. - # e.g. if there are 20 leap year days between 2 dates having the same day - # and month then the based on 365 days calculation - # the distance in years will come out to over 80 years when in written - # english it would read better as about 80 years. - minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year + if from_time.acts_like?(:time) && to_time.acts_like?(:time) + fyear = from_time.year + fyear += 1 if from_time.month >= 3 + tyear = to_time.year + tyear -= 1 if to_time.month < 3 + leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)} + minute_offset_for_leap_year = leap_years * 1440 + # Discount the leap year days when calculating year distance. + # e.g. if there are 20 leap year days between 2 dates having the same day + # and month then the based on 365 days calculation + # the distance in years will come out to over 80 years when in written + # english it would read better as about 80 years. + minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year + else + minutes_with_offset = distance_in_minutes + end remainder = (minutes_with_offset % 525600) distance_in_years = (minutes_with_offset / 525600) if remainder < 131400 diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 3f5829d86a..ad097f2eb7 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -184,7 +184,7 @@ module ActionView # First name: <%= f.text_field :first_name %> # Last name : <%= f.text_field :last_name %> # Biography : <%= text_area :person, :biography %> - # Admin? : <%= check_box_tag "person[admin]", @person.company.admin? %> + # Admin? : <%= check_box_tag "person[admin]", "1", @person.company.admin? %> # <%= f.submit %> # <% end %> # diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index eb806f44cf..12bb162da2 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -112,9 +112,9 @@ module ActionView def highlight(text, phrases, *args) options = args.extract_options! unless args.empty? - options[:highlighter] = args[0] || '<mark>\1</mark>' + options[:highlighter] = args[0] end - options.reverse_merge!(:highlighter => '<mark>\1</mark>') + options[:highlighter] ||= '<mark>\1</mark>' text = sanitize(text) unless options[:sanitize] == false if text.blank? || phrases.blank? @@ -157,19 +157,20 @@ module ActionView options = args.extract_options! unless args.empty? - options[:radius] = args[0] || 100 - options[:omission] = args[1] || "..." + options[:radius] = args[0] + options[:omission] = args[1] end - options.reverse_merge!(:radius => 100, :omission => "...") + radius = options[:radius] || 100 + omission = options[:omission] || "..." phrase = Regexp.escape(phrase) return unless found_pos = text =~ /(#{phrase})/i - start_pos = [ found_pos - options[:radius], 0 ].max - end_pos = [ [ found_pos + phrase.length + options[:radius] - 1, 0].max, text.length ].min + start_pos = [ found_pos - radius, 0 ].max + end_pos = [ [ found_pos + phrase.length + radius - 1, 0].max, text.length ].min - prefix = start_pos > 0 ? options[:omission] : "" - postfix = end_pos < text.length - 1 ? options[:omission] : "" + prefix = start_pos > 0 ? omission : "" + postfix = end_pos < text.length - 1 ? omission : "" prefix + text[start_pos..end_pos].strip + postfix end @@ -218,12 +219,12 @@ module ActionView def word_wrap(text, *args) options = args.extract_options! unless args.blank? - options[:line_width] = args[0] || 80 + options[:line_width] = args[0] end - options.reverse_merge!(:line_width => 80) + line_width = options[:line_width] || 80 text.split("\n").collect do |line| - line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line + line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line end * "\n" end diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 8b53867aea..34ea06c9cf 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -451,7 +451,7 @@ module ActionView end def retrieve_variable(path) - variable = @options[:as].try(:to_sym) || path[%r'_?(\w+)(\.\w+)*$', 1].to_sym + variable = @options.fetch(:as) { path[%r'_?(\w+)(\.\w+)*$', 1] }.try(:to_sym) variable_counter = :"#{variable}_counter" if @collection [variable, variable_counter] end 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 9c51db135b..48e2d6491e 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -60,11 +60,6 @@ class RescueController < ActionController::Base render :text => exception.message end - # This is a Dispatcher exception and should be in ApplicationController. - rescue_from ActionController::RoutingError do - render :text => 'no way' - end - rescue_from ActionView::TemplateError do render :text => 'action_view templater error' end @@ -343,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/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/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index c9b8a5bb70..4835bc578f 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -125,13 +125,33 @@ class DateHelperTest < ActionView::TestCase start_date = Date.new 1982, 12, 3 end_date = Date.new 2010, 11, 30 assert_equal("almost 28 years", distance_of_time_in_words(start_date, end_date)) + assert_equal("almost 28 years", distance_of_time_in_words(end_date, start_date)) end def test_distance_in_words_with_integers - assert_equal "less than a minute", distance_of_time_in_words(59) + assert_equal "1 minute", distance_of_time_in_words(59) assert_equal "about 1 hour", distance_of_time_in_words(60*60) - assert_equal "less than a minute", distance_of_time_in_words(0, 59) + assert_equal "1 minute", distance_of_time_in_words(0, 59) assert_equal "about 1 hour", distance_of_time_in_words(60*60, 0) + assert_equal "about 3 years", distance_of_time_in_words(10**8) + assert_equal "about 3 years", distance_of_time_in_words(0, 10**8) + end + + def test_distance_in_words_with_times + assert_equal "1 minute", distance_of_time_in_words(30.seconds) + assert_equal "1 minute", distance_of_time_in_words(59.seconds) + assert_equal "2 minutes", distance_of_time_in_words(119.seconds) + assert_equal "2 minutes", distance_of_time_in_words(1.minute + 59.seconds) + assert_equal "3 minutes", distance_of_time_in_words(2.minute + 30.seconds) + assert_equal "44 minutes", distance_of_time_in_words(44.minutes + 29.seconds) + assert_equal "about 1 hour", distance_of_time_in_words(44.minutes + 30.seconds) + assert_equal "about 1 hour", distance_of_time_in_words(60.minutes) + + # include seconds + assert_equal "half a minute", distance_of_time_in_words(39.seconds, 0, true) + assert_equal "less than a minute", distance_of_time_in_words(40.seconds, 0, true) + assert_equal "less than a minute", distance_of_time_in_words(59.seconds, 0, true) + assert_equal "1 minute", distance_of_time_in_words(60.seconds, 0, true) end def test_time_ago_in_words 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/render_test.rb b/actionpack/test/template/render_test.rb index 122b07d348..43b176df3c 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -21,9 +21,7 @@ module RenderTestCases end def test_render_without_options - @view.render() - flunk "Render did not raise ArgumentError" - rescue ArgumentError => e + e = assert_raises(ArgumentError) { @view.render() } assert_match "You invoked render but did not give any of :partial, :template, :inline, :file or :text option.", e.message end @@ -153,25 +151,26 @@ module RenderTestCases end def test_render_partial_with_invalid_name - @view.render(:partial => "test/200") - flunk "Render did not raise ArgumentError" - rescue ArgumentError => e + e = assert_raises(ArgumentError) { @view.render(:partial => "test/200") } assert_equal "The partial name (test/200) is not a valid Ruby identifier; " + - "make sure your partial name starts with a letter or underscore, " + - "and is followed by any combinations of letters, numbers, or underscores.", e.message + "make sure your partial name starts with a letter or underscore, " + + "and is followed by any combinations of letters, numbers, or underscores.", e.message + end + + def test_render_partial_with_missing_filename + e = assert_raises(ArgumentError) { @view.render(:partial => "test/") } + assert_equal "The partial name (test/) is not a valid Ruby identifier; " + + "make sure your partial name starts with a letter or underscore, " + + "and is followed by any combinations of letters, numbers, or underscores.", e.message end def test_render_partial_with_incompatible_object - @view.render(:partial => nil) - flunk "Render did not raise ArgumentError" - rescue ArgumentError => e + e = assert_raises(ArgumentError) { @view.render(:partial => nil) } assert_equal "'#{nil.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.", e.message end def test_render_partial_with_errors - @view.render(:partial => "test/raise") - flunk "Render did not raise Template::Error" - rescue ActionView::Template::Error => e + e = assert_raises(ActionView::Template::Error) { @view.render(:partial => "test/raise") } assert_match %r!method.*doesnt_exist!, e.message assert_equal "", e.sub_template_message assert_equal "1", e.line_number @@ -180,9 +179,7 @@ module RenderTestCases end def test_render_sub_template_with_errors - @view.render(:template => "test/sub_template_raise") - flunk "Render did not raise Template::Error" - rescue ActionView::Template::Error => e + e = assert_raises(ActionView::Template::Error) { @view.render(:template => "test/sub_template_raise") } assert_match %r!method.*doesnt_exist!, e.message assert_equal "Trace of template inclusion: #{File.expand_path("#{FIXTURE_LOAD_PATH}/test/sub_template_raise.html.erb")}", e.sub_template_message assert_equal "1", e.line_number @@ -190,9 +187,7 @@ module RenderTestCases end def test_render_file_with_errors - @view.render(:file => File.expand_path("test/_raise", FIXTURE_LOAD_PATH)) - flunk "Render did not raise Template::Error" - rescue ActionView::Template::Error => e + e = assert_raises(ActionView::Template::Error) { @view.render(:file => File.expand_path("test/_raise", FIXTURE_LOAD_PATH)) } assert_match %r!method.*doesnt_exist!, e.message assert_equal "", e.sub_template_message assert_equal "1", e.line_number @@ -274,7 +269,7 @@ module RenderTestCases # TODO: The reason for this test is unclear, improve documentation def test_render_missing_xml_partial_and_raise_missing_template @view.formats = [:xml] - assert_raise(ActionView::MissingTemplate) { @view.render(:partial => "test/layout_for_partial") } + assert_raises(ActionView::MissingTemplate) { @view.render(:partial => "test/layout_for_partial") } ensure @view.formats = nil end @@ -325,7 +320,7 @@ module RenderTestCases def test_render_ignores_templates_with_malformed_template_handlers ActiveSupport::Deprecation.silence do %w(malformed malformed.erb malformed.html.erb malformed.en.html.erb).each do |name| - assert_raise(ActionView::MissingTemplate) { @view.render(:file => "test/malformed/#{name}") } + assert_raises(ActionView::MissingTemplate) { @view.render(:file => "test/malformed/#{name}") } end end end @@ -450,23 +445,15 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_incompatible_external_encoding with_external_encoding Encoding::SHIFT_JIS do - begin - @view.render(:file => "test/utf8", :formats => [:html], :layouts => "layouts/yield") - flunk 'Should have raised incompatible encoding error' - rescue ActionView::Template::Error => error - assert_match 'Your template was not saved as valid Shift_JIS', error.original_exception.message - end + e = assert_raises(ActionView::Template::Error) { @view.render(:file => "test/utf8", :formats => [:html], :layouts => "layouts/yield") } + assert_match 'Your template was not saved as valid Shift_JIS', e.original_exception.message end end def test_render_utf8_template_with_partial_with_incompatible_encoding with_external_encoding Encoding::SHIFT_JIS do - begin - @view.render(:file => "test/utf8_magic_with_bare_partial", :formats => [:html], :layouts => "layouts/yield") - flunk 'Should have raised incompatible encoding error' - rescue ActionView::Template::Error => error - assert_match 'Your template was not saved as valid Shift_JIS', error.original_exception.message - end + e = assert_raises(ActionView::Template::Error) { @view.render(:file => "test/utf8_magic_with_bare_partial", :formats => [:html], :layouts => "layouts/yield") } + assert_match 'Your template was not saved as valid Shift_JIS', e.original_exception.message end 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/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 016bf87d86..0c628c33c2 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -130,12 +130,12 @@ module ActiveModel # has more than one error message, yields once for each error message. # # p.errors.add(:name, "can't be blank") - # p.errors.each do |attribute, errors_array| + # p.errors.each do |attribute, error| # # Will yield :name and "can't be blank" # end # # p.errors.add(:name, "must be specified") - # p.errors.each do |attribute, errors_array| + # p.errors.each do |attribute, error| # # Will yield :name and "can't be blank" # # then yield :name and "must be specified" # end diff --git a/activemodel/lib/active_model/model.rb b/activemodel/lib/active_model/model.rb index 6825fdc653..3af95b09b0 100644 --- a/activemodel/lib/active_model/model.rb +++ b/activemodel/lib/active_model/model.rb @@ -2,11 +2,11 @@ module ActiveModel # == Active Model Basic Model # - # Includes the required interface for an object to interact with +ActionPack+, - # using different +ActiveModel+ modules. It includes model name introspections, + # Includes the required interface for an object to interact with <tt>ActionPack</tt>, + # using different <tt>ActiveModel</tt> modules. It includes model name introspections, # conversions, translations and validations. Besides that, it allows you to # initialize the object with a hash of attributes, pretty much like - # +ActiveRecord+ does. + # <tt>ActiveRecord</tt> does. # # A minimal implementation could be: # @@ -19,8 +19,8 @@ module ActiveModel # person.name # => 'bob' # person.age # => 18 # - # Note that, by default, +ActiveModel::Model+ implements +persisted?+ to - # return +false+, which is the most common case. You may want to override it + # Note that, by default, <tt>ActiveModel::Model</tt> implements <tt>persisted?</tt> to + # return <tt>false</tt>, which is the most common case. You may want to override it # in your class to simulate a different scenario: # # class Person @@ -35,14 +35,14 @@ module ActiveModel # person = Person.new(:id => 1, :name => 'bob') # person.persisted? # => true # - # Also, if for some reason you need to run code on +initialize+, make sure you + # Also, if for some reason you need to run code on <tt>initialize</tt>, make sure you # call super if you want the attributes hash initialization to happen. # # class Person # include ActiveModel::Model # attr_accessor :id, :name, :omg # - # def initialize(attributes) + # def initialize(attributes={}) # super # @omg ||= true # end @@ -52,7 +52,7 @@ module ActiveModel # person.omg # => true # # For more detailed information on other functionalities available, please refer - # to the specific modules included in +ActiveModel::Model+ (see below). + # to the specific modules included in <tt>ActiveModel::Model</tt> (see below). module Model def self.included(base) base.class_eval do diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb index b905d2b6d2..a6b6dfafe7 100644 --- a/activemodel/lib/active_model/observing.rb +++ b/activemodel/lib/active_model/observing.rb @@ -70,8 +70,8 @@ module ActiveModel end # Notify list of observers of a change. - def notify_observers(*arg) - observer_instances.each { |observer| observer.update(*arg) } + def notify_observers(*args) + observer_instances.each { |observer| observer.update(*args) } end # Total number of observers. @@ -221,6 +221,7 @@ module ActiveModel end # Start observing the declared classes and their subclasses. + # Called automatically by the instance method. def initialize observed_classes.each { |klass| add_observer!(klass) } end @@ -249,6 +250,7 @@ module ActiveModel klass.add_observer(self) end + # Returns true if notifications are disabled for this object. def disabled_for?(object) klass = object.class return false unless klass.respond_to?(:observers) diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb index e7a57cf691..ff2213231f 100644 --- a/activemodel/lib/active_model/secure_password.rb +++ b/activemodel/lib/active_model/secure_password.rb @@ -55,17 +55,13 @@ module ActiveModel module InstanceMethodsOnActivation # Returns self if the password is correct, otherwise false. def authenticate(unencrypted_password) - if BCrypt::Password.new(password_digest) == unencrypted_password - self - else - false - end + BCrypt::Password.new(password_digest) == unencrypted_password && self end # Encrypts the password into the password_digest attribute. def password=(unencrypted_password) - @password = unencrypted_password unless unencrypted_password.blank? + @password = unencrypted_password self.password_digest = BCrypt::Password.create(unencrypted_password) end end diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb index c39c85e1af..dbafd0bd1a 100644 --- a/activemodel/lib/active_model/validations/callbacks.rb +++ b/activemodel/lib/active_model/validations/callbacks.rb @@ -8,7 +8,8 @@ module ActiveModel # Provides an interface for any class to have <tt>before_validation</tt> and # <tt>after_validation</tt> callbacks. # - # First, extend ActiveModel::Callbacks from the class you are creating: + # First, include ActiveModel::Validations::Callbacks from the class you are + # creating: # # class MyModel # include ActiveModel::Validations::Callbacks diff --git a/activemodel/test/cases/secure_password_test.rb b/activemodel/test/cases/secure_password_test.rb index 4338a3fc53..c451cc1aca 100644 --- a/activemodel/test/cases/secure_password_test.rb +++ b/activemodel/test/cases/secure_password_test.rb @@ -19,6 +19,12 @@ class SecurePasswordTest < ActiveModel::TestCase assert !@user.valid?, 'user should be invalid' end + test "blank password doesn't override previous password" do + @user.password = 'test' + @user.password = '' + assert_equal @user.password, 'test' + end + test "password must be present" do assert !@user.valid? assert_equal 1, @user.errors.size diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 85cb3e0e20..aa84dacf07 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,27 @@ ## Rails 4.0.0 (unreleased) ## +* Added an :index option to automatically create indexes for references + and belongs_to statements in migrations. + + The `references` and `belongs_to` methods now support an `index` + option that receives either a boolean value or an options hash + that is identical to options available to the add_index method: + + create_table :messages do |t| + t.references :person, :index => true + end + + Is the same as: + + create_table :messages do |t| + t.references :person + end + add_index :messages, :person_id + + Generators have also been updated to use the new syntax. + + [Joshua Wood] + * Added bang methods for mutating `ActiveRecord::Relation` objects. For example, while `foo.where(:bar)` will return a new object leaving `foo` unchanged, `foo.where!(:bar)` will mutate the foo @@ -217,7 +239,7 @@ * PostgreSQL hstore types are automatically deserialized from the database. -## Rails 3.2.3 (unreleased) ## +## Rails 3.2.3 (March 30, 2012) ## * Added find_or_create_by_{attribute}! dynamic method. *Andrew White* diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 561e48d52e..a609867898 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -2,6 +2,7 @@ require 'thread' require 'monitor' require 'set' require 'active_support/core_ext/module/deprecation' +require 'timeout' module ActiveRecord # Raised when a connection could not be obtained within the connection @@ -11,9 +12,6 @@ module ActiveRecord # Raised when a connection pool is full and another connection is requested class PoolFullError < ConnectionNotEstablished - def initialize size, timeout - super("Connection pool of size #{size} and timeout #{timeout}s is full") - end end module ConnectionAdapters @@ -94,6 +92,21 @@ module ActiveRecord attr_accessor :automatic_reconnect, :timeout attr_reader :spec, :connections, :size, :reaper + class Latch # :nodoc: + def initialize + @mutex = Mutex.new + @cond = ConditionVariable.new + end + + def release + @mutex.synchronize { @cond.broadcast } + end + + def await + @mutex.synchronize { @cond.wait @mutex } + end + end + # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification # object which describes database connection information (e.g. adapter, # host name, username, password, etc), as well as the maximum size for @@ -115,6 +128,7 @@ module ActiveRecord # default max pool size to 5 @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5 + @latch = Latch.new @connections = [] @automatic_reconnect = true end @@ -139,8 +153,10 @@ module ActiveRecord # #release_connection releases the connection-thread association # and returns the connection to the pool. def release_connection(with_id = current_connection_id) - conn = @reserved_connections.delete(with_id) - checkin conn if conn + synchronize do + conn = @reserved_connections.delete(with_id) + checkin conn if conn + end end # If a connection already exists yield it to the block. If no connection @@ -205,23 +221,23 @@ module ActiveRecord # Raises: # - PoolFullError: no connection can be obtained from the pool. def checkout - # Checkout an available connection - synchronize do - # Try to find a connection that hasn't been leased, and lease it - conn = connections.find { |c| c.lease } - - # If all connections were leased, and we have room to expand, - # create a new connection and lease it. - if !conn && connections.size < size - conn = checkout_new_connection - conn.lease - end + loop do + # Checkout an available connection + synchronize do + # Try to find a connection that hasn't been leased, and lease it + conn = connections.find { |c| c.lease } + + # If all connections were leased, and we have room to expand, + # create a new connection and lease it. + if !conn && connections.size < size + conn = checkout_new_connection + conn.lease + end - if conn - checkout_and_verify conn - else - raise PoolFullError.new(size, timeout) + return checkout_and_verify(conn) if conn end + + Timeout.timeout(@timeout, PoolFullError) { @latch.await } end end @@ -238,6 +254,7 @@ module ActiveRecord release conn end + @latch.release end # Remove a connection from the connection pool. The connection will @@ -250,6 +267,7 @@ module ActiveRecord # from the reserved hash will be a little easier. release conn end + @latch.release end # Removes dead connections from the pool. A dead connection can occur @@ -262,6 +280,7 @@ module ActiveRecord remove conn if conn.in_use? && stale > conn.last_use && !conn.active? end end + @latch.release end private diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 7ee8f40631..3546873550 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -65,11 +65,12 @@ module ActiveRecord class TableDefinition # An array of ColumnDefinition objects, representing the column changes # that have been defined. - attr_accessor :columns + attr_accessor :columns, :indexes def initialize(base) @columns = [] @columns_hash = {} + @indexes = {} @base = base end @@ -212,19 +213,22 @@ module ActiveRecord # # TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type # column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of - # options, these will be used when creating the <tt>_type</tt> column. So what can be written like this: + # options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option + # will also create an index, similar to calling <tt>add_index</tt>. So what can be written like this: # # create_table :taggings do |t| # t.integer :tag_id, :tagger_id, :taggable_id # t.string :tagger_type # t.string :taggable_type, :default => 'Photo' # end + # add_index :taggings, :tag_id, :name => 'index_taggings_on_tag_id' + # add_index :taggings, [:tagger_id, :tagger_type] # # Can also be written as follows using references: # # create_table :taggings do |t| - # t.references :tag - # t.references :tagger, :polymorphic => true + # t.references :tag, :index => { :name => 'index_taggings_on_tag_id' } + # t.references :tagger, :polymorphic => true, :index => true # t.references :taggable, :polymorphic => { :default => 'Photo' } # end def column(name, type, options = {}) @@ -255,6 +259,14 @@ module ActiveRecord end # end EOV end + + # Adds index options to the indexes hash, keyed by column name + # This is primarily used to track indexes that need to be created after the table + # === Examples + # index(:account_id, :name => 'index_projects_on_account_id') + def index(column_name, options = {}) + indexes[column_name] = options + end # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and # <tt>:updated_at</tt> to the table. @@ -267,9 +279,11 @@ module ActiveRecord def references(*args) options = args.extract_options! polymorphic = options.delete(:polymorphic) + index_options = options.delete(:index) args.each do |col| column("#{col}_id", :integer, options) column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil? + index(polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options end end alias :belongs_to :references @@ -435,9 +449,11 @@ module ActiveRecord def references(*args) options = args.extract_options! polymorphic = options.delete(:polymorphic) + index_options = options.delete(:index) args.each do |col| @base.add_column(@table_name, "#{col}_id", :integer, options) @base.add_column(@table_name, "#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil? + @base.add_index(@table_name, polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options end end alias :belongs_to :references diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 0784b2d11a..30a4f9aa35 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -171,6 +171,7 @@ module ActiveRecord create_sql << td.to_sql create_sql << ") #{options[:options]}" execute create_sql + td.indexes.each_pair { |c,o| add_index table_name, c, o } end # Creates a new join table with the name created using the lexical order of the first two @@ -375,7 +376,7 @@ module ActiveRecord # Note: SQLite doesn't support index length # # ====== Creating an index with a sort order (desc or asc, asc is the default) - # add_index(:accounts, [:branch_id, :party_id, :surname], :order => {:branch_id => :desc, :part_id => :asc}) + # add_index(:accounts, [:branch_id, :party_id, :surname], :order => {:branch_id => :desc, :party_id => :asc}) # generates # CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname) # diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index d0ea468430..a848838a4e 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -516,7 +516,7 @@ module ActiveRecord def pk_and_sequence_for(table) execute_and_free("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA') do |result| create_table = each_hash(result).first[:"Create Table"] - if create_table.to_s =~ /PRIMARY KEY\s+\((.+)\)/ + if create_table.to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/ keys = $1.split(",").map { |key| key.delete('`"') } keys.length == 1 ? [keys.first, nil] : nil else diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb index c85d590ce1..7f38dda11e 100644 --- a/activerecord/lib/active_record/model_schema.rb +++ b/activerecord/lib/active_record/model_schema.rb @@ -172,8 +172,8 @@ module ActiveRecord end def reset_sequence_name #:nodoc: - @sequence_name = connection.default_sequence_name(table_name, primary_key) @explicit_sequence_name = false + @sequence_name = connection.default_sequence_name(table_name, primary_key) end # Sets the name of the sequence to use when generating ids to the given diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 8d6ed4c6d1..0dbaab306f 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -257,39 +257,26 @@ module ActiveRecord # Customer.update_all :wants_email => true # # # Update all books with 'Rails' in their title - # Book.update_all "author = 'David'", "title LIKE '%Rails%'" - # - # # Update all avatars migrated more recently than a week ago - # Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago] - # - # # Update all books that match conditions, but limit it to 5 ordered by date - # Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5 - # - # # Conditions from the current relation also works # Book.where('title LIKE ?', '%Rails%').update_all(:author => 'David') # - # # The same idea applies to limit and order + # # Update all books that match conditions, but limit it to 5 ordered by date # Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(:author => 'David') - def update_all(updates, conditions = nil, options = {}) - if conditions || options.present? - where(conditions).apply_finder_options(options.slice(:limit, :order)).update_all(updates) - else - stmt = Arel::UpdateManager.new(arel.engine) + def update_all(updates) + stmt = Arel::UpdateManager.new(arel.engine) - stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates)) - stmt.table(table) - stmt.key = table[primary_key] + stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates)) + stmt.table(table) + stmt.key = table[primary_key] - if joins_values.any? - @klass.connection.join_to_update(stmt, arel) - else - stmt.take(arel.limit) - stmt.order(*arel.orders) - stmt.wheres = arel.constraints - end - - @klass.connection.update stmt, 'SQL', bind_values + if joins_values.any? + @klass.connection.join_to_update(stmt, arel) + else + stmt.take(arel.limit) + stmt.order(*arel.orders) + stmt.wheres = arel.constraints end + + @klass.connection.update stmt, 'SQL', bind_values end # Updates an object (or multiple objects) and saves it to the database, if validations pass. diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 2fd89882ff..15f838a5ab 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -46,19 +46,14 @@ module ActiveRecord # group.each { |person| person.party_all_night! } # end def find_in_batches(options = {}) + options.assert_valid_keys(:start, :batch_size) + relation = self unless arel.orders.blank? && arel.taken.blank? ActiveRecord::Base.logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size") end - if (finder_options = options.except(:start, :batch_size)).present? - raise "You can't specify an order, it's forced to be #{batch_order}" if options[:order].present? - raise "You can't specify a limit, it's forced to be the batch_size" if options[:limit].present? - - relation = apply_finder_options(finder_options) - end - start = options.delete(:start).to_i batch_size = options.delete(:batch_size) || 1000 diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 6bb2c7af81..db894c8aa9 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -3,56 +3,19 @@ require 'active_support/core_ext/object/try' module ActiveRecord module Calculations - # Count operates using three different approaches. + # Count the records. # - # * Count all: By not passing any parameters to count, it will return a count of all the rows for the model. - # * Count using column: By passing a column name to count, it will return a count of all the - # rows for the model with supplied column present. - # * Count using options will find the row count matched by the options used. + # Person.count + # # => the total count of all people # - # The third approach, count using options, accepts an option hash as the only parameter. The options are: + # Person.count(:age) + # # => returns the total count of all people whose age is present in database # - # * <tt>:conditions</tt>: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. - # See conditions in the intro to ActiveRecord::Base. - # * <tt>:joins</tt>: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" - # (rarely needed) or named associations in the same form used for the <tt>:include</tt> option, which will - # perform an INNER JOIN on the associated table(s). If the value is a string, then the records - # will be returned read-only since they will have attributes that do not correspond to the table's columns. - # Pass <tt>:readonly => false</tt> to override. - # * <tt>:include</tt>: Named associations that should be loaded alongside using LEFT OUTER JOINs. - # The symbols named refer to already defined associations. When using named associations, count - # returns the number of DISTINCT items for the model you're counting. - # See eager loading under Associations. - # * <tt>:order</tt>: An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations). - # * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause. - # * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you, for example, - # want to do a join but not include the joined columns. - # * <tt>:distinct</tt>: Set this to true to make this a distinct calculation, such as - # SELECT COUNT(DISTINCT posts.id) ... - # * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an - # alternate table name (or even the name of a database view). + # Person.count(:all) + # # => performs a COUNT(*) (:all is an alias for '*') # - # Examples for counting all: - # Person.count # returns the total count of all people - # - # Examples for counting by column: - # Person.count(:age) # returns the total count of all people whose age is present in database - # - # Examples for count with options: - # Person.count(:conditions => "age > 26") - # - # # because of the named association, it finds the DISTINCT count using LEFT OUTER JOIN. - # Person.count(:conditions => "age > 26 AND job.salary > 60000", :include => :job) - # - # # finds the number of rows matching the conditions and joins. - # Person.count(:conditions => "age > 26 AND job.salary > 60000", - # :joins => "LEFT JOIN jobs on jobs.person_id = person.id") - # - # Person.count('id', :conditions => "age > 26") # Performs a COUNT(id) - # Person.count(:all, :conditions => "age > 26") # Performs a COUNT(*) (:all is an alias for '*') - # - # Note: <tt>Person.count(:all)</tt> will not work because it will use <tt>:all</tt> as the condition. - # Use Person.count instead. + # Person.count(:age, distinct: true) + # # => counts the number of different age values def count(column_name = nil, options = {}) column_name, options = nil, column_name if column_name.is_a?(Hash) calculate(:count, column_name, options) @@ -98,21 +61,22 @@ module ActiveRecord end # This calculates aggregate values in the given column. Methods for count, sum, average, - # minimum, and maximum have been added as shortcuts. Options such as <tt>:conditions</tt>, - # <tt>:order</tt>, <tt>:group</tt>, <tt>:having</tt>, and <tt>:joins</tt> can be passed to customize the query. + # minimum, and maximum have been added as shortcuts. # # There are two basic forms of output: + # # * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float # for AVG, and the given column's type for everything else. - # * Grouped values: This returns an ordered hash of the values and groups them by the - # <tt>:group</tt> option. It takes either a column name, or the name of a belongs_to association. # - # values = Person.maximum(:age, :group => 'last_name') + # * Grouped values: This returns an ordered hash of the values and groups them. It + # takes either a column name, or the name of a belongs_to association. + # + # values = Person.group('last_name').maximum(:age) # puts values["Drake"] # => 43 # # drake = Family.find_by_last_name('Drake') - # values = Person.maximum(:age, :group => :family) # Person belongs_to :family + # values = Person.group(:family).maximum(:age) # Person belongs_to :family # puts values[drake] # => 43 # @@ -120,47 +84,25 @@ module ActiveRecord # ... # end # - # Options: - # * <tt>:conditions</tt> - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. - # See conditions in the intro to ActiveRecord::Base. - # * <tt>:include</tt>: Eager loading, see Associations for details. Since calculations don't load anything, - # the purpose of this is to access fields on joined tables in your conditions, order, or group clauses. - # * <tt>:joins</tt> - An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id". - # (Rarely needed). - # The records will be returned read-only since they will have attributes that do not correspond to the - # table's columns. - # * <tt>:order</tt> - An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations). - # * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause. - # * <tt>:select</tt> - By default, this is * as in SELECT * FROM, but can be changed if you for example - # want to do a join, but not include the joined columns. - # * <tt>:distinct</tt> - Set this to true to make this a distinct calculation, such as - # SELECT COUNT(DISTINCT posts.id) ... - # # Examples: # Person.calculate(:count, :all) # The same as Person.count # Person.average(:age) # SELECT AVG(age) FROM people... - # Person.minimum(:age, :conditions => ['last_name != ?', 'Drake']) # Selects the minimum age for - # # everyone with a last name other than 'Drake' # # # Selects the minimum age for any family without any minors - # Person.minimum(:age, :having => 'min(age) > 17', :group => :last_name) + # Person.group(:last_name).having("min(age) > 17").minimum(:age) # # Person.sum("2 * age") def calculate(operation, column_name, options = {}) - if options.except(:distinct).present? - apply_finder_options(options.except(:distinct)).calculate(operation, column_name, :distinct => options[:distinct]) - else - relation = with_default_scope - - if relation.equal?(self) - if eager_loading? || (includes_values.present? && references_eager_loaded_tables?) - construct_relation_for_association_calculations.calculate(operation, column_name, options) - else - perform_calculation(operation, column_name, options) - end + relation = with_default_scope + + if relation.equal?(self) + if eager_loading? || (includes_values.present? && references_eager_loaded_tables?) + construct_relation_for_association_calculations.calculate(operation, column_name, options) else - relation.calculate(operation, column_name, options) + perform_calculation(operation, column_name, options) end + else + relation.calculate(operation, column_name, options) end rescue ThrowResult 0 diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 87f6822a3d..416b55f5c5 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -3,54 +3,12 @@ require 'active_support/core_ext/hash/indifferent_access' module ActiveRecord module FinderMethods - # Find operates with four different retrieval approaches: - # - # * Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). - # If no record can be found for all of the listed ids, then RecordNotFound will be raised. If the primary key - # is an integer, find by id coerces its arguments using +to_i+. - # * Find first - This will return the first record matched by the options used. These options can either be specific - # conditions or merely an order. If no record can be matched, +nil+ is returned. Use - # <tt>Model.find(:first, *args)</tt> or its shortcut <tt>Model.first(*args)</tt>. - # * Find last - This will return the last record matched by the options used. These options can either be specific - # conditions or merely an order. If no record can be matched, +nil+ is returned. Use - # <tt>Model.find(:last, *args)</tt> or its shortcut <tt>Model.last(*args)</tt>. - # * Find all - This will return all the records matched by the options used. - # If no records are found, an empty array is returned. Use - # <tt>Model.find(:all, *args)</tt> or its shortcut <tt>Model.all(*args)</tt>. - # - # All approaches accept an options hash as their last parameter. - # - # ==== Options - # - # * <tt>:conditions</tt> - An SQL fragment like "administrator = 1", <tt>["user_name = ?", username]</tt>, - # or <tt>["user_name = :user_name", { :user_name => user_name }]</tt>. See conditions in the intro. - # * <tt>:order</tt> - An SQL fragment like "created_at DESC, name". - # * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause. - # * <tt>:having</tt> - Combined with +:group+ this can be used to filter the records that a - # <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause. - # * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned. - # * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, - # it would skip rows 0 through 4. - # * <tt>:joins</tt> - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed), - # named associations in the same form used for the <tt>:include</tt> option, which will perform an - # <tt>INNER JOIN</tt> on the associated table(s), - # or an array containing a mixture of both strings and named associations. - # If the value is a string, then the records will be returned read-only since they will - # have attributes that do not correspond to the table's columns. - # Pass <tt>:readonly => false</tt> to override. - # * <tt>:include</tt> - Names associations that should be loaded alongside. The symbols named refer - # to already defined associations. See eager loading under Associations. - # * <tt>:select</tt> - By default, this is "*" as in "SELECT * FROM", but can be changed if you, - # for example, want to do a join but not include the joined columns. Takes a string with the SELECT SQL fragment (e.g. "id, name"). - # * <tt>:from</tt> - By default, this is the table name of the class, but can be changed - # to an alternate table name (or even the name of a database view). - # * <tt>:readonly</tt> - Mark the returned records read-only so they cannot be saved or updated. - # * <tt>:lock</tt> - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE". - # <tt>:lock => true</tt> gives connection's default exclusive lock, usually "FOR UPDATE". + # Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). + # If no record can be found for all of the listed ids, then RecordNotFound will be raised. If the primary key + # is an integer, find by id coerces its arguments using +to_i+. # # ==== Examples # - # # find by id # Person.find(1) # returns the object for ID = 1 # Person.find("1") # returns the object for ID = 1 # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6) @@ -59,29 +17,10 @@ module ActiveRecord # Person.where("administrator = 1").order("created_on DESC").find(1) # # Note that returned records may not be in the same order as the ids you - # provide since database rows are unordered. Give an explicit <tt>:order</tt> + # provide since database rows are unordered. Give an explicit <tt>order</tt> # to ensure the results are sorted. # - # ==== Examples - # - # # find first - # Person.first # returns the first object fetched by SELECT * FROM people - # Person.where(["user_name = ?", user_name]).first - # Person.where(["user_name = :u", { :u => user_name }]).first - # Person.order("created_on DESC").offset(5).first - # - # # find last - # Person.last # returns the last object fetched by SELECT * FROM people - # Person.where(["user_name = ?", user_name]).last - # Person.order("created_on DESC").offset(5).last - # - # # find all - # Person.all # returns an array of objects for all the rows fetched by SELECT * FROM people - # Person.where(["category IN (?)", categories]).limit(50).all - # Person.where({ :friends => ["Bob", "Steve", "Fred"] }).all - # Person.offset(10).limit(10).all - # Person.includes([:account, :friends]).all - # Person.group("category").all + # ==== Find with lock # # Example for find with a lock: Imagine two concurrent transactions: # each will read <tt>person.visits == 2</tt>, add 1 to it, and save, resulting @@ -95,19 +34,10 @@ module ActiveRecord # person.save! # end def find(*args) - return to_a.find { |*block_args| yield(*block_args) } if block_given? - - options = args.extract_options! - - if options.present? - apply_finder_options(options).find(*args) + if block_given? + to_a.find { |*block_args| yield(*block_args) } else - case args.first - when :first, :last, :all - send(args.first) - else - find_with_ids(*args) - end + find_with_ids(*args) end end @@ -130,18 +60,14 @@ module ActiveRecord where(*args).first! end - # A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the - # same arguments to this method as you can to <tt>find(:first)</tt>. - def first(*args) - if args.any? - if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) - limit(*args).to_a - else - apply_finder_options(args.first).first - end - else - find_first - end + # Examples: + # + # Person.first # returns the first object fetched by SELECT * FROM people + # Person.where(["user_name = ?", user_name]).first + # Person.where(["user_name = :u", { :u => user_name }]).first + # Person.order("created_on DESC").offset(5).first + def first(limit = nil) + limit ? limit(limit).to_a : find_first end # Same as +first+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record @@ -150,18 +76,17 @@ module ActiveRecord first or raise RecordNotFound end - # A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the - # same arguments to this method as you can to <tt>find(:last)</tt>. - def last(*args) - if args.any? - if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) - if order_values.empty? - order("#{primary_key} DESC").limit(*args).reverse - else - to_a.last(*args) - end + # Examples: + # + # Person.last # returns the last object fetched by SELECT * FROM people + # Person.where(["user_name = ?", user_name]).last + # Person.order("created_on DESC").offset(5).last + def last(limit = nil) + if limit + if order_values.empty? + order("#{primary_key} DESC").limit(limit).reverse else - apply_finder_options(args.first).last + to_a.last(limit) end else find_last @@ -174,10 +99,16 @@ module ActiveRecord last or raise RecordNotFound end - # A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the - # same arguments to this method as you can to <tt>find(:all)</tt>. - def all(*args) - args.any? ? apply_finder_options(args.first).to_a : to_a + # Examples: + # + # Person.all # returns an array of objects for all the rows fetched by SELECT * FROM people + # Person.where(["category IN (?)", categories]).limit(50).all + # Person.where({ :friends => ["Bob", "Steve", "Fred"] }).all + # Person.offset(10).limit(10).all + # Person.includes([:account, :friends]).all + # Person.group("category").all + def all + to_a end # Returns true if a record exists in the table that matches the +id+ or diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 7bf9c16959..1d2151fdb2 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -5,6 +5,20 @@ require 'active_record/relation/merger' module ActiveRecord module SpawnMethods + + # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>. + # Returns an array representing the union of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array. + # + # ==== Examples + # + # Post.where(:published => true).joins(:comments).merge( Comment.where(:spam => false) ) + # # Performs a single join query with both where conditions. + # + # recent_posts = Post.order('created_at DESC').first(5) + # Post.where(:published => true).merge(recent_posts) + # # Returns the union of all published posts with the 5 most recently created posts. + # # (This is just an example. You'd probably want to do this with a single query!) + # def merge(other) if other.is_a?(Array) to_a & other diff --git a/activerecord/lib/rails/generators/active_record/model/model_generator.rb b/activerecord/lib/rails/generators/active_record/model/model_generator.rb index f3bb70fb41..8e6ef20285 100644 --- a/activerecord/lib/rails/generators/active_record/model/model_generator.rb +++ b/activerecord/lib/rails/generators/active_record/model/model_generator.rb @@ -14,6 +14,7 @@ module ActiveRecord def create_migration_file return unless options[:migration] && options[:parent].nil? + attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false migration_template "migration.rb", "db/migrate/create_#{table_name}.rb" end @@ -27,7 +28,7 @@ module ActiveRecord end def attributes_with_index - attributes.select { |a| a.has_index? || (a.reference? && options[:indexes]) } + attributes.select { |a| !a.reference? && a.has_index? } end def accessible_attributes diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb index 5aa4743e7b..475a292f85 100644 --- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb +++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb @@ -56,6 +56,36 @@ module ActiveRecord end end + def test_pk_and_sequence_for + pk, seq = @conn.pk_and_sequence_for('ex') + assert_equal 'id', pk + assert_equal @conn.default_sequence_name('ex', 'id'), seq + end + + def test_pk_and_sequence_for_with_non_standard_primary_key + @conn.exec_query('drop table if exists ex_with_non_standard_pk') + @conn.exec_query(<<-eosql) + CREATE TABLE `ex_with_non_standard_pk` ( + `code` INT(11) DEFAULT NULL auto_increment, + PRIMARY KEY (`code`)) + eosql + pk, seq = @conn.pk_and_sequence_for('ex_with_non_standard_pk') + assert_equal 'code', pk + assert_equal @conn.default_sequence_name('ex_with_non_standard_pk', 'code'), seq + end + + def test_pk_and_sequence_for_with_custom_index_type_pk + @conn.exec_query('drop table if exists ex_with_custom_index_type_pk') + @conn.exec_query(<<-eosql) + CREATE TABLE `ex_with_custom_index_type_pk` ( + `id` INT(11) DEFAULT NULL auto_increment, + PRIMARY KEY USING BTREE (`id`)) + eosql + pk, seq = @conn.pk_and_sequence_for('ex_with_custom_index_type_pk') + assert_equal 'id', pk + assert_equal @conn.default_sequence_name('ex_with_custom_index_type_pk', 'id'), seq + end + private def insert(ctx, data) binds = data.map { |name, value| diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index f7f44208b3..196de34094 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -61,8 +61,8 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_loading_conditions_with_or - posts = authors(:david).posts.find( - :all, :include => :comments, :references => :comments, + posts = authors(:david).posts.references(:comments).find( + :all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'" ) assert_nil posts.detect { |p| p.author_id != authors(:david).id }, @@ -276,25 +276,25 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_nested_loading_through_has_one_association_with_conditions - aa = AuthorAddress.find( + aa = AuthorAddress.references(:author_addresses).find( author_addresses(:david_address).id, :include => {:author => :posts}, - :conditions => "author_addresses.id > 0", :references => :author_addresses + :conditions => "author_addresses.id > 0" ) assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_conditions_on_association - aa = AuthorAddress.find( + aa = AuthorAddress.references(:authors).find( author_addresses(:david_address).id, :include => {:author => :posts}, - :conditions => "authors.id > 0", :references => :authors + :conditions => "authors.id > 0" ) assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_conditions_on_nested_association - aa = AuthorAddress.find( + aa = AuthorAddress.references(:posts).find( author_addresses(:david_address).id, :include => {:author => :posts}, - :conditions => "posts.id > 0", :references => :posts + :conditions => "posts.id > 0" ) assert_equal aa.author.posts.count, aa.author.posts.length end @@ -564,9 +564,9 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions assert_queries(1) do - posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, - :conditions => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ], - :references => [:authors, :comments]) + posts = Post.references(:authors, :comments). + find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, + :conditions => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ]) assert_equal 0, posts.size end end @@ -592,7 +592,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional author = authors(:david) author_posts_without_comments = author.posts.select { |post| post.comments.blank? } - assert_equal author_posts_without_comments.size, author.posts.count(:all, :include => :comments, :conditions => 'comments.id is null', :references => :comments) + assert_equal author_posts_without_comments.size, author.posts.includes(:comments).where('comments.id is null').references(:comments).count end def test_eager_count_performed_on_a_has_many_through_association_with_multi_table_conditional @@ -628,75 +628,75 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers - posts = authors(:david).posts.find(:all, - :include => :comments, - :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'", - :references => :comments, - :limit => 2 - ) + posts = + authors(:david).posts + .includes(:comments) + .where("comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'") + .references(:comments) + .limit(2) + .to_a assert_equal 2, posts.size - count = Post.count( - :include => [ :comments, :author ], - :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')", - :references => [:authors, :comments], - :limit => 2 - ) + count = + Post.includes(:comments, :author) + .where("authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')") + .references(:authors, :comments) + .limit(2) + .count assert_equal count, posts.size end def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers posts = nil - Post.send(:with_scope, :find => { - :include => :comments, - :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'", - :references => :comments - }) do - posts = authors(:david).posts.find(:all, :limit => 2) + Post.includes(:comments) + .where("comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'") + .references(:comments) + .scoping do + + posts = authors(:david).posts.limit(2).to_a assert_equal 2, posts.size end - Post.send(:with_scope, :find => { - :include => [ :comments, :author ], - :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')", - :references => [:authors, :comments] - }) do - count = Post.count(:limit => 2) + Post.includes(:comments, :author) + .where("authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')") + .references(:authors, :comments) + .scoping do + + count = Post.limit(2).count assert_equal count, posts.size end end def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers Post.send(:with_scope, :find => { :conditions => "1=1" }) do - posts = authors(:david).posts.find(:all, - :include => :comments, - :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'", - :references => :comments, - :limit => 2 - ) + posts = + authors(:david).posts + .includes(:comments) + .where("comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'") + .references(:comments) + .limit(2) + .to_a assert_equal 2, posts.size - count = Post.count( - :include => [ :comments, :author ], - :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')", - :references => [:authors, :comments], - :limit => 2 - ) + count = Post.includes(:comments, :author) + .where("authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')") + .references(:authors, :comments) + .limit(2) + .count assert_equal count, posts.size end end def test_eager_with_scoped_order_using_association_limiting_without_explicit_scope - posts_with_explicit_order = Post.find( - :all, :conditions => 'comments.id is not null', :references => :comments, - :include => :comments, :order => 'posts.id DESC', :limit => 2 - ) - posts_with_scoped_order = Post.send(:with_scope, :find => {:order => 'posts.id DESC'}) do - Post.find( - :all, :conditions => 'comments.id is not null', - :references => :comments, :include => :comments, :limit => 2 - ) + posts_with_explicit_order = + Post.where('comments.id is not null').references(:comments) + .includes(:comments).order('posts.id DESC').limit(2) + + posts_with_scoped_order = Post.order('posts.id DESC').scoping do + Post.where('comments.id is not null').references(:comments) + .includes(:comments).limit(2) end + assert_equal posts_with_explicit_order, posts_with_scoped_order end @@ -844,10 +844,9 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_limited_eager_with_numeric_in_association assert_equal( people(:david, :susan), - Person.find( + Person.references(:number1_fans_people).find( :all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", - :references => :number1_fans_people, :order => 'people.id', :limit => 2, :offset => 0 ) ) @@ -965,11 +964,11 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_count_with_include if current_adapter?(:SybaseAdapter) - assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15", :references => :comments) + assert_equal 3, authors(:david).posts_with_comments.where("len(comments.body) > 15").references(:comments).count elsif current_adapter?(:OpenBaseAdapter) - assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(FETCHBLOB(comments.body)) > 15", :references => :comments) + assert_equal 3, authors(:david).posts_with_comments.where("length(FETCHBLOB(comments.body)) > 15").references(:comments).count else - assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15", :references => :comments) + assert_equal 3, authors(:david).posts_with_comments.where("length(comments.body) > 15").references(:comments).count end end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index f457dfb9b3..f5f5b96aa7 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -681,8 +681,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_join_table_alias assert_equal( 3, - Developer.find( - :all, :include => {:projects => :developers}, :references => :developers_projects_join, + Developer.references(:developers_projects_join).find( + :all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL' ).size ) @@ -697,9 +697,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal( 3, - Developer.find( + Developer.references(:developers_projects_join).find( :all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', - :references => :developers_projects_join, :group => group.join(",") + :group => group.join(",") ).size ) end diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index 301755249c..dde5b26a88 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -362,7 +362,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end assert_raise ActiveRecord::EagerLoadPolymorphicError do - tags(:general).taggings.find(:all, :include => :taggable, :references => :bogus_table, :conditions => 'bogus_table.column = 1') + tags(:general).taggings.includes(:taggable).where('bogus_table.column = 1').references(:bogus_table).to_a end end diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index d15487ab11..d555c1699e 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -627,7 +627,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase def test_a_child_marked_for_destruction_should_not_be_destroyed_twice @pirate.ship.mark_for_destruction assert @pirate.save - @pirate.ship.expects(:destroy).never + class << @pirate.ship + def destroy; raise "Should not be called" end + end assert @pirate.save end @@ -672,7 +674,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase def test_a_parent_marked_for_destruction_should_not_be_destroyed_twice @ship.pirate.mark_for_destruction assert @ship.save - @ship.pirate.expects(:destroy).never + class << @ship.pirate + def destroy; raise "Should not be called" end + end assert @ship.save end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 5fb49d540f..ef22936e18 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1503,7 +1503,11 @@ class BasicsTest < ActiveRecord::TestCase after_seq = Joke.sequence_name assert_not_equal before_columns, after_columns - assert_not_equal before_seq, after_seq unless before_seq.blank? && after_seq.blank? + unless before_seq.nil? && after_seq.nil? + assert_not_equal before_seq, after_seq + assert_equal "cold_jokes_id_seq", before_seq + assert_equal "funny_jokes_id_seq", after_seq + end end def test_dont_clear_sequence_name_when_setting_explicitly @@ -1514,7 +1518,7 @@ class BasicsTest < ActiveRecord::TestCase Joke.table_name = "funny_jokes" after_seq = Joke.sequence_name - assert_equal before_seq, after_seq unless before_seq.blank? && after_seq.blank? + assert_equal before_seq, after_seq unless before_seq.nil? && after_seq.nil? end def test_dont_clear_inheritnce_column_when_setting_explicitly diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 0391319a00..48cb05e36e 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -49,12 +49,12 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_get_maximum_of_field_with_include - assert_equal 55, Account.maximum(:credit_limit, :include => :firm, :references => :companies, :conditions => "companies.name != 'Summit'") + assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(:credit_limit) end def test_should_get_maximum_of_field_with_scoped_include - Account.send :with_scope, :find => { :include => :firm, :references => :companies, :conditions => "companies.name != 'Summit'" } do - assert_equal 55, Account.maximum(:credit_limit) + Account.send :with_scope, :find => { :include => :firm } do + assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).maximum(:credit_limit) end end @@ -270,10 +270,10 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_not_modify_options_when_using_includes - options = {:conditions => 'companies.id > 1', :include => :firm, :references => :companies} + options = {:conditions => 'companies.id > 1', :include => :firm} options_copy = options.dup - Account.count(:all, options) + Account.references(:companies).count(:all, options) assert_equal options_copy, options end diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index da93500ce3..8dc9f761c2 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -96,6 +96,30 @@ module ActiveRecord end end + def test_full_pool_blocks + cs = @pool.size.times.map { @pool.checkout } + t = Thread.new { @pool.checkout } + + # make sure our thread is in the timeout section + Thread.pass until t.status == "sleep" + + connection = cs.first + connection.close + assert_equal connection, t.join.value + end + + def test_removing_releases_latch + cs = @pool.size.times.map { @pool.checkout } + t = Thread.new { @pool.checkout } + + # make sure our thread is in the timeout section + Thread.pass until t.status == "sleep" + + connection = cs.first + @pool.remove connection + assert_respond_to t.join.value, :execute + end + def test_reap_and_active @pool.checkout @pool.checkout diff --git a/activerecord/test/cases/explain_test.rb b/activerecord/test/cases/explain_test.rb index 83c9b6e107..cb7781f8e7 100644 --- a/activerecord/test/cases/explain_test.rb +++ b/activerecord/test/cases/explain_test.rb @@ -28,7 +28,9 @@ if ActiveRecord::Base.connection.supports_explain? original = base.logger base.logger = nil - base.logger.expects(:warn).never + class << base.logger + def warn; raise "Should not be called" end + end with_threshold(0) do car = Car.where(:name => 'honda').first diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 96c8eb6417..70f3c4bcc5 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -1182,9 +1182,9 @@ class FinderTest < ActiveRecord::TestCase end def test_with_limiting_with_custom_select - posts = Post.find( + posts = Post.references(:authors).find( :all, :include => :author, :select => ' posts.*, authors.id as "author_id"', - :references => :authors, :limit => 3, :order => 'posts.id' + :limit => 3, :order => 'posts.id' ) assert_equal 3, posts.size assert_equal [0, 1, 1], posts.map(&:author_id).sort diff --git a/activerecord/test/cases/migration/references_index_test.rb b/activerecord/test/cases/migration/references_index_test.rb new file mode 100644 index 0000000000..8ab1c59724 --- /dev/null +++ b/activerecord/test/cases/migration/references_index_test.rb @@ -0,0 +1,99 @@ +require 'cases/helper' + +module ActiveRecord + class Migration + class ReferencesIndexTest < ActiveRecord::TestCase + attr_reader :connection, :table_name + + def setup + super + @connection = ActiveRecord::Base.connection + @table_name = :testings + end + + def teardown + super + connection.drop_table :testings rescue nil + end + + def test_creates_index + connection.create_table table_name do |t| + t.references :foo, :index => true + end + + assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + end + + def test_does_not_create_index + connection.create_table table_name do |t| + t.references :foo + end + + refute connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + end + + def test_does_not_create_index_explicit + connection.create_table table_name do |t| + t.references :foo, :index => false + end + + refute connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + end + + def test_creates_index_with_options + connection.create_table table_name do |t| + t.references :foo, :index => {:name => :index_testings_on_yo_momma} + t.references :bar, :index => {:unique => true} + end + + assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_yo_momma) + assert connection.index_exists?(table_name, :bar_id, :name => :index_testings_on_bar_id, :unique => true) + end + + def test_creates_polymorphic_index + connection.create_table table_name do |t| + t.references :foo, :polymorphic => true, :index => true + end + + assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type) + end + + def test_creates_index_for_existing_table + connection.create_table table_name + connection.change_table table_name do |t| + t.references :foo, :index => true + end + + assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + end + + def test_does_not_create_index_for_existing_table + connection.create_table table_name + connection.change_table table_name do |t| + t.references :foo + end + + refute connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + end + + def test_does_not_create_index_for_existing_table_explicit + connection.create_table table_name + connection.change_table table_name do |t| + t.references :foo, :index => false + end + + refute connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + end + + def test_creates_polymorphic_index_for_existing_table + connection.create_table table_name + connection.change_table table_name do |t| + t.references :foo, :polymorphic => true, :index => true + end + + assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type) + end + + end + end +end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 92dc150104..e14c2d072c 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -36,7 +36,7 @@ class MigrationTest < ActiveRecord::TestCase ActiveRecord::Base.connection.initialize_schema_migrations_table ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}" - %w(things awesome_things prefix_things_suffix prefix_awesome_things_suffix).each do |table| + %w(things awesome_things prefix_things_suffix p_awesome_things_s ).each do |table| Thing.connection.drop_table(table) rescue nil end Thing.reset_column_information @@ -278,8 +278,8 @@ class MigrationTest < ActiveRecord::TestCase def test_rename_table_with_prefix_and_suffix assert !Thing.table_exists? - ActiveRecord::Base.table_name_prefix = 'prefix_' - ActiveRecord::Base.table_name_suffix = '_suffix' + ActiveRecord::Base.table_name_prefix = 'p_' + ActiveRecord::Base.table_name_suffix = '_s' Thing.reset_table_name Thing.reset_sequence_name WeNeedThings.up @@ -288,7 +288,7 @@ class MigrationTest < ActiveRecord::TestCase assert_equal "hello world", Thing.find(:first).content RenameThings.up - Thing.table_name = "prefix_awesome_things_suffix" + Thing.table_name = "p_awesome_things_s" assert_equal "hello world", Thing.find(:first).content ensure @@ -404,6 +404,7 @@ end class ChangeTableMigrationsTest < ActiveRecord::TestCase def setup @connection = Person.connection + @connection.stubs(:add_index) @connection.create_table :delete_me, :force => true do |t| end end diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb index f7a5d05582..e0fdd2871c 100644 --- a/activerecord/test/cases/modules_test.rb +++ b/activerecord/test/cases/modules_test.rb @@ -72,7 +72,7 @@ class ModulesTest < ActiveRecord::TestCase clients = [] assert_nothing_raised NameError, "Should be able to resolve all class constants via reflection" do - clients << MyApplication::Business::Client.find(3, :include => {:firm => :account}, :conditions => 'accounts.id IS NOT NULL', :references => :accounts) + clients << MyApplication::Business::Client.references(:accounts).find(3, :include => {:firm => :account}, :conditions => 'accounts.id IS NOT NULL') clients << MyApplication::Business::Client.find(3, :include => {:firm => :account}) end diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 719b96fa0f..9ef703fd9b 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -128,12 +128,6 @@ module ActiveRecord assert_equal ['foo'], relation.references_values end - def test_apply_finder_options_takes_references - relation = Relation.new :a, :b - relation = relation.apply_finder_options(:references => :foo) - assert_equal ['foo'], relation.references_values - end - test 'merging a hash into a relation' do relation = Relation.new :a, :b relation = relation.merge where: ['lol'], readonly: true diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec index d26d71b615..2c874e932e 100644 --- a/activesupport/activesupport.gemspec +++ b/activesupport/activesupport.gemspec @@ -19,6 +19,6 @@ Gem::Specification.new do |s| s.rdoc_options.concat ['--encoding', 'UTF-8'] s.add_dependency('i18n', '~> 0.6') - s.add_dependency('multi_json', '~> 1.0') + s.add_dependency('multi_json', '~> 1.3') s.add_dependency('tzinfo', '~> 0.3.31') end diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 5076697c04..7add47be44 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -1,5 +1,4 @@ require 'active_support/duration' -require 'active_support/core_ext/time/zones' require 'active_support/core_ext/time/conversions' class Time diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb index 0c5962858e..b4ed74a7b0 100644 --- a/activesupport/lib/active_support/core_ext/time/zones.rb +++ b/activesupport/lib/active_support/core_ext/time/zones.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/time/calculations' require 'active_support/time_with_zone' class Time diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb index cbeb6c0a28..986a764479 100644 --- a/activesupport/lib/active_support/json/decoding.rb +++ b/activesupport/lib/active_support/json/decoding.rb @@ -9,7 +9,7 @@ module ActiveSupport module JSON class << self def decode(json, options ={}) - data = MultiJson.decode(json, options) + data = MultiJson.load(json, options) if ActiveSupport.parse_json_times convert_dates_from(data) else @@ -18,12 +18,12 @@ module ActiveSupport end def engine - MultiJson.engine + MultiJson.adapter end alias :backend :engine def engine=(name) - MultiJson.engine = name + MultiJson.use(name) end alias :backend= :engine= diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index 8cf7bdafda..6735c561d3 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -4,7 +4,7 @@ require 'active_support/notifications/fanout' module ActiveSupport # = Notifications # - # +ActiveSupport::Notifications+ provides an instrumentation API for Ruby. + # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for Ruby. # # == Instrumenters # @@ -44,26 +44,53 @@ module ActiveSupport # event.duration # => 10 (in milliseconds) # event.payload # => { :extra => :information } # - # The block in the +subscribe+ call gets the name of the event, start + # The block in the <tt>subscribe</tt> call gets the name of the event, start # timestamp, end timestamp, a string with a unique identifier for that event # (something like "535801666f04d0298cd6"), and a hash with the payload, in # that order. # # If an exception happens during that particular instrumentation the payload will - # have a key +:exception+ with an array of two elements as value: a string with + # have a key <tt>:exception</tt> with an array of two elements as value: a string with # the name of the exception class, and the exception message. # - # As the previous example depicts, the class +ActiveSupport::Notifications::Event+ + # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt> # is able to take the arguments as they come and provide an object-oriented # interface to that data. # + # It is also possible to pass an object as the second parameter passed to the + # <tt>subscribe</tt> method instead of a block: + # + # module ActionController + # class PageRequest + # def call(name, started, finished, unique_id, payload) + # Rails.logger.debug ["notification:", name, started, finished, unique_id, payload].join(" ") + # end + # end + # end + # + # ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new) + # + # resulting in the following output within the logs including a hash with the payload: + # + # notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 { + # :controller=>"Devise::SessionsController", + # :action=>"new", + # :params=>{"action"=>"new", "controller"=>"devise/sessions"}, + # :format=>:html, + # :method=>"GET", + # :path=>"/login/sign_in", + # :status=>200, + # :view_runtime=>279.3080806732178, + # :db_runtime=>40.053 + # } + # # You can also subscribe to all events whose name matches a certain regexp: # # ActiveSupport::Notifications.subscribe(/render/) do |*args| # ... # end # - # and even pass no argument to +subscribe+, in which case you are subscribing + # and even pass no argument to <tt>subscribe</tt>, in which case you are subscribing # to all events. # # == Temporary Subscriptions diff --git a/activesupport/lib/active_support/time/autoload.rb b/activesupport/lib/active_support/time/autoload.rb deleted file mode 100644 index c9a7731b39..0000000000 --- a/activesupport/lib/active_support/time/autoload.rb +++ /dev/null @@ -1,5 +0,0 @@ -module ActiveSupport - autoload :Duration, 'active_support/duration' - autoload :TimeWithZone, 'active_support/time_with_zone' - autoload :TimeZone, 'active_support/values/time_zone' -end diff --git a/guides/assets/images/getting_started/form_with_errors.png b/guides/assets/images/getting_started/form_with_errors.png Binary files differnew file mode 100644 index 0000000000..badefe6ea6 --- /dev/null +++ b/guides/assets/images/getting_started/form_with_errors.png diff --git a/guides/assets/images/getting_started/show_action_for_posts.png b/guides/assets/images/getting_started/show_action_for_posts.png Binary files differnew file mode 100644 index 0000000000..5c8c4d8e5e --- /dev/null +++ b/guides/assets/images/getting_started/show_action_for_posts.png diff --git a/guides/assets/images/posts_index.png b/guides/assets/images/posts_index.png Binary files differdeleted file mode 100644 index f6cd2f9b80..0000000000 --- a/guides/assets/images/posts_index.png +++ /dev/null diff --git a/guides/code/getting_started/Gemfile b/guides/code/getting_started/Gemfile index 768985070c..ab4e34b2d0 100644 --- a/guides/code/getting_started/Gemfile +++ b/guides/code/getting_started/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails', '3.2.0' +gem 'rails', '3.2.3' # Bundle edge Rails instead: # gem 'rails', :git => 'git://github.com/rails/rails.git' @@ -15,7 +15,7 @@ group :assets do gem 'coffee-rails', '~> 3.2.1' # See https://github.com/sstephenson/execjs#readme for more supported runtimes - # gem 'therubyracer' + # gem 'therubyracer', :platform => :ruby gem 'uglifier', '>= 1.0.3' end @@ -28,7 +28,7 @@ gem 'jquery-rails' # To use Jbuilder templates for JSON # gem 'jbuilder' -# Use unicorn as the web server +# Use unicorn as the app server # gem 'unicorn' # Deploy with Capistrano diff --git a/guides/code/getting_started/app/assets/javascripts/comments.js.coffee b/guides/code/getting_started/app/assets/javascripts/comments.js.coffee deleted file mode 100644 index 761567942f..0000000000 --- a/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/guides/code/getting_started/app/assets/javascripts/home.js.coffee b/guides/code/getting_started/app/assets/javascripts/home.js.coffee deleted file mode 100644 index 761567942f..0000000000 --- a/guides/code/getting_started/app/assets/javascripts/home.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/guides/code/getting_started/app/assets/javascripts/posts.js.coffee b/guides/code/getting_started/app/assets/javascripts/posts.js.coffee deleted file mode 100644 index 761567942f..0000000000 --- a/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/guides/code/getting_started/app/assets/stylesheets/comments.css.scss b/guides/code/getting_started/app/assets/stylesheets/comments.css.scss deleted file mode 100644 index e730912783..0000000000 --- a/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +++ /dev/null @@ -1,3 +0,0 @@ -// Place all the styles related to the Comments controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/guides/code/getting_started/app/assets/stylesheets/home.css.scss b/guides/code/getting_started/app/assets/stylesheets/home.css.scss deleted file mode 100644 index f0ddc6846a..0000000000 --- a/guides/code/getting_started/app/assets/stylesheets/home.css.scss +++ /dev/null @@ -1,3 +0,0 @@ -// Place all the styles related to the home controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/guides/code/getting_started/app/assets/stylesheets/posts.css.scss b/guides/code/getting_started/app/assets/stylesheets/posts.css.scss deleted file mode 100644 index ed4dfd10f2..0000000000 --- a/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +++ /dev/null @@ -1,3 +0,0 @@ -// Place all the styles related to the Posts controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/guides/code/getting_started/app/assets/stylesheets/scaffolds.css.scss b/guides/code/getting_started/app/assets/stylesheets/scaffolds.css.scss deleted file mode 100644 index 05188f08ed..0000000000 --- a/guides/code/getting_started/app/assets/stylesheets/scaffolds.css.scss +++ /dev/null @@ -1,56 +0,0 @@ -body { - background-color: #fff; - color: #333; - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; } - -p, ol, ul, td { - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; } - -pre { - background-color: #eee; - padding: 10px; - font-size: 11px; } - -a { - color: #000; - &:visited { - color: #666; } - &:hover { - color: #fff; - background-color: #000; } } - -div { - &.field, &.actions { - margin-bottom: 10px; } } - -#notice { - color: green; } - -.field_with_errors { - padding: 2px; - background-color: red; - display: table; } - -#error_explanation { - width: 450px; - border: 2px solid red; - padding: 7px; - padding-bottom: 0; - margin-bottom: 20px; - background-color: #f0f0f0; - h2 { - text-align: left; - font-weight: bold; - padding: 5px 5px 5px 15px; - font-size: 12px; - margin: -7px; - margin-bottom: 0px; - background-color: #c00; - color: #fff; } - ul li { - font-size: 12px; - list-style: square; } } diff --git a/guides/code/getting_started/app/controllers/home_controller.rb b/guides/code/getting_started/app/controllers/home_controller.rb index 6cc31c1ca3..309b70441e 100644 --- a/guides/code/getting_started/app/controllers/home_controller.rb +++ b/guides/code/getting_started/app/controllers/home_controller.rb @@ -1,4 +1,4 @@ -class HomeController < ApplicationController +class WelcomeController < ApplicationController def index end diff --git a/guides/code/getting_started/app/controllers/posts_controller.rb b/guides/code/getting_started/app/controllers/posts_controller.rb index 1581d4eb16..947cd2a767 100644 --- a/guides/code/getting_started/app/controllers/posts_controller.rb +++ b/guides/code/getting_started/app/controllers/posts_controller.rb @@ -1,84 +1,24 @@ class PostsController < ApplicationController - http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index - # GET /posts - # GET /posts.json + def index @posts = Post.all - - respond_to do |format| - format.html # index.html.erb - format.json { render json: @posts } - end end - # GET /posts/1 - # GET /posts/1.json def show @post = Post.find(params[:id]) - - respond_to do |format| - format.html # show.html.erb - format.json { render json: @post } - end end - # GET /posts/new - # GET /posts/new.json def new @post = Post.new - - respond_to do |format| - format.html # new.html.erb - format.json { render json: @post } - end - end - - # GET /posts/1/edit - def edit - @post = Post.find(params[:id]) end - # POST /posts - # POST /posts.json def create @post = Post.new(params[:post]) - respond_to do |format| - if @post.save - format.html { redirect_to @post, notice: 'Post was successfully created.' } - format.json { render json: @post, status: :created, location: @post } - else - format.html { render action: "new" } - format.json { render json: @post.errors, status: :unprocessable_entity } - end - end - end - - # PUT /posts/1 - # PUT /posts/1.json - def update - @post = Post.find(params[:id]) - - respond_to do |format| - if @post.update_attributes(params[:post]) - format.html { redirect_to @post, notice: 'Post was successfully updated.' } - format.json { head :no_content } - else - format.html { render action: "edit" } - format.json { render json: @post.errors, status: :unprocessable_entity } - end - end - end - - # DELETE /posts/1 - # DELETE /posts/1.json - def destroy - @post = Post.find(params[:id]) - @post.destroy - - respond_to do |format| - format.html { redirect_to posts_url } - format.json { head :no_content } + if @post.save + redirect_to :action => :show, :id => @post.id + else + render 'new' end end end diff --git a/guides/code/getting_started/app/helpers/home_helper.rb b/guides/code/getting_started/app/helpers/home_helper.rb index 23de56ac60..eeead45fc9 100644 --- a/guides/code/getting_started/app/helpers/home_helper.rb +++ b/guides/code/getting_started/app/helpers/home_helper.rb @@ -1,2 +1,2 @@ -module HomeHelper +module WelcomeHelper end diff --git a/guides/code/getting_started/app/helpers/posts_helper.rb b/guides/code/getting_started/app/helpers/posts_helper.rb index b6e8e67894..a7b8cec898 100644 --- a/guides/code/getting_started/app/helpers/posts_helper.rb +++ b/guides/code/getting_started/app/helpers/posts_helper.rb @@ -1,5 +1,2 @@ module PostsHelper - def join_tags(post) - post.tags.map { |t| t.name }.join(", ") - end end diff --git a/guides/code/getting_started/app/models/post.rb b/guides/code/getting_started/app/models/post.rb index 61c2b5ae44..21387340b0 100644 --- a/guides/code/getting_started/app/models/post.rb +++ b/guides/code/getting_started/app/models/post.rb @@ -1,11 +1,6 @@ class Post < ActiveRecord::Base - validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 } - + has_many :comments, :dependent => :destroy - has_many :tags - - accepts_nested_attributes_for :tags, :allow_destroy => :true, - :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } end diff --git a/guides/code/getting_started/app/models/tag.rb b/guides/code/getting_started/app/models/tag.rb deleted file mode 100644 index 30992e8ba9..0000000000 --- a/guides/code/getting_started/app/models/tag.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Tag < ActiveRecord::Base - belongs_to :post -end diff --git a/guides/code/getting_started/app/views/home/index.html.erb b/guides/code/getting_started/app/views/home/index.html.erb deleted file mode 100644 index bb4f3dcd1f..0000000000 --- a/guides/code/getting_started/app/views/home/index.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<h1>Hello, Rails!</h1> -<%= link_to "My Blog", posts_path %> 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 e27da7f413..18cb29f335 100644 --- a/guides/code/getting_started/app/views/posts/_form.html.erb +++ b/guides/code/getting_started/app/views/posts/_form.html.erb @@ -1,32 +1,25 @@ -<% @post.tags.build %> -<%= form_for(@post) do |post_form| %> +<%= form_for :post, :url => { :action => :create } 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> + <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 %> - - <div class="field"> - <%= post_form.label :name %><br /> - <%= post_form.text_field :name %> - </div> - <div class="field"> - <%= post_form.label :title %><br /> - <%= post_form.text_field :title %> - </div> - <div class="field"> - <%= post_form.label :content %><br /> - <%= post_form.text_area :content %> - </div> - <h2>Tags</h2> - <%= render :partial => 'tags/form', - :locals => {:form => post_form} %> - <div class="actions"> - <%= post_form.submit %> - </div> + <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 %> 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 45dee1b25f..455a74b17f 100644 --- a/guides/code/getting_started/app/views/posts/index.html.erb +++ b/guides/code/getting_started/app/views/posts/index.html.erb @@ -1,27 +1,19 @@ <h1>Listing posts</h1> +<%= link_to 'New post', :action => :new %> + <table> <tr> - <th>Name</th> <th>Title</th> - <th>Content</th> - <th></th> - <th></th> + <th>Text</th> <th></th> </tr> <% @posts.each do |post| %> <tr> - <td><%= post.name %></td> <td><%= post.title %></td> - <td><%= post.content %></td> - <td><%= link_to 'Show', post %></td> - <td><%= link_to 'Edit', edit_post_path(post) %></td> - <td><%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete %></td> + <td><%= post.text %></td> + <td><%= link_to 'Show', :action => :show, :id => post.id %> </tr> <% end %> </table> - -<br /> - -<%= link_to 'New Post', new_post_path %> diff --git a/guides/code/getting_started/app/views/posts/new.html.erb b/guides/code/getting_started/app/views/posts/new.html.erb index 36ad7421f9..ce9523a721 100644 --- a/guides/code/getting_started/app/views/posts/new.html.erb +++ b/guides/code/getting_started/app/views/posts/new.html.erb @@ -2,4 +2,4 @@ <%= render 'form' %> -<%= link_to 'Back', posts_path %> +<%= link_to 'Back', :action => :index %> 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 da78a9527b..a79fadfe4c 100644 --- a/guides/code/getting_started/app/views/posts/show.html.erb +++ b/guides/code/getting_started/app/views/posts/show.html.erb @@ -1,31 +1,11 @@ -<p class="notice"><%= notice %></p> - <p> - <b>Name:</b> - <%= @post.name %> -</p> - -<p> - <b>Title:</b> + <strong>Title:</strong> <%= @post.title %> </p> - -<p> - <b>Content:</b> - <%= @post.content %> -</p> - + <p> - <b>Tags:</b> - <%= join_tags(@post) %> + <strong>Text:</strong> + <%= @post.text %> </p> - -<h2>Comments</h2> -<%= render @post.comments %> - -<h2>Add a comment:</h2> -<%= render "comments/form" %> - - -<%= link_to 'Edit Post', edit_post_path(@post) %> | -<%= link_to 'Back to Posts', posts_path %> | + +<%= link_to 'Back', :action => :index %> diff --git a/guides/code/getting_started/app/views/tags/_form.html.erb b/guides/code/getting_started/app/views/tags/_form.html.erb deleted file mode 100644 index 7e424b0e20..0000000000 --- a/guides/code/getting_started/app/views/tags/_form.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -<%= form.fields_for :tags do |tag_form| %> - <div class="field"> - <%= tag_form.label :name, 'Tag:' %> - <%= tag_form.text_field :name %> - </div> - <% unless tag_form.object.nil? || tag_form.object.new_record? %> - <div class="field"> - <%= tag_form.label :_destroy, 'Remove:' %> - <%= tag_form.check_box :_destroy %> - </div> - <% end %> -<% end %> diff --git a/guides/code/getting_started/app/views/welcome/index.html.erb b/guides/code/getting_started/app/views/welcome/index.html.erb new file mode 100644 index 0000000000..e04680ea7e --- /dev/null +++ b/guides/code/getting_started/app/views/welcome/index.html.erb @@ -0,0 +1,2 @@ +<h1>Hello, Rails!</h1> +<%= link_to "My Blog", :controller => "posts" %> diff --git a/guides/code/getting_started/config/routes.rb b/guides/code/getting_started/config/routes.rb index b048ac68f1..10009a35cf 100644 --- a/guides/code/getting_started/config/routes.rb +++ b/guides/code/getting_started/config/routes.rb @@ -1,9 +1,12 @@ Blog::Application.routes.draw do - resources :posts do - resources :comments - end + # resources :posts do + # resources :comments + # end - get "home/index" + get "posts" => "posts#index" + get "posts/new" + post "posts/create" + get "posts/:id" => "posts#show" # The priority is based upon order of creation: # first created -> highest priority. @@ -54,8 +57,8 @@ Blog::Application.routes.draw do # You can have the root of your site routed with "root" # just remember to delete public/index.html. - root :to => "home#index" - + root :to => "welcome#index" + # See how all your routes lay out with "rake routes" # This is a legacy wild controller route that's not recommended for RESTful applications. diff --git a/guides/code/getting_started/db/migrate/20110901013701_create_tags.rb b/guides/code/getting_started/db/migrate/20110901013701_create_tags.rb deleted file mode 100644 index cf95b1c3d0..0000000000 --- a/guides/code/getting_started/db/migrate/20110901013701_create_tags.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateTags < ActiveRecord::Migration - def change - create_table :tags do |t| - t.string :name - t.references :post - - t.timestamps - end - add_index :tags, :post_id - end -end diff --git a/guides/code/getting_started/db/migrate/20110901012504_create_posts.rb b/guides/code/getting_started/db/migrate/20120420083127_create_posts.rb index d45a961523..602bef31ab 100644 --- a/guides/code/getting_started/db/migrate/20110901012504_create_posts.rb +++ b/guides/code/getting_started/db/migrate/20120420083127_create_posts.rb @@ -1,9 +1,8 @@ class CreatePosts < ActiveRecord::Migration def change create_table :posts do |t| - t.string :name t.string :title - t.text :content + t.text :text t.timestamps end diff --git a/guides/code/getting_started/db/schema.rb b/guides/code/getting_started/db/schema.rb index 9db4fbe4b6..cfb56ca9b9 100644 --- a/guides/code/getting_started/db/schema.rb +++ b/guides/code/getting_started/db/schema.rb @@ -11,31 +11,30 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20110901013701) do +ActiveRecord::Schema.define(:version => 20120420083127) do create_table "comments", :force => true do |t| t.string "commenter" t.text "body" t.integer "post_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "comments", ["post_id"], :name => "index_comments_on_post_id" create_table "posts", :force => true do |t| - t.string "name" t.string "title" - t.text "content" - t.datetime "created_at" - t.datetime "updated_at" + t.text "text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "tags", :force => true do |t| t.string "name" t.integer "post_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "tags", ["post_id"], :name => "index_tags_on_post_id" diff --git a/guides/code/getting_started/test/fixtures/posts.yml b/guides/code/getting_started/test/fixtures/posts.yml index 8b0f75a33d..e1edfd385e 100644 --- a/guides/code/getting_started/test/fixtures/posts.yml +++ b/guides/code/getting_started/test/fixtures/posts.yml @@ -1,11 +1,9 @@ # Read about fixtures at http://api.rubyonrails.org/classes/Fixtures.html one: - name: MyString title: MyString - content: MyText + text: MyText two: - name: MyString title: MyString - content: MyText + text: MyText diff --git a/guides/code/getting_started/test/functional/home_controller_test.rb b/guides/code/getting_started/test/functional/home_controller_test.rb index 0d9bb47c3e..dff8e9d2c5 100644 --- a/guides/code/getting_started/test/functional/home_controller_test.rb +++ b/guides/code/getting_started/test/functional/home_controller_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class HomeControllerTest < ActionController::TestCase +class WelcomeControllerTest < ActionController::TestCase test "should get index" do get :index assert_response :success diff --git a/guides/code/getting_started/vendor/assets/stylesheets/.gitkeep b/guides/code/getting_started/vendor/assets/stylesheets/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 --- a/guides/code/getting_started/vendor/assets/stylesheets/.gitkeep +++ /dev/null diff --git a/guides/source/active_record_querying.textile b/guides/source/active_record_querying.textile index de55401c1f..58eae2ee0f 100644 --- a/guides/source/active_record_querying.textile +++ b/guides/source/active_record_querying.textile @@ -539,7 +539,9 @@ And this will give you a single +Order+ object for each date where there are ord The SQL that would be executed would be something like this: <sql> -SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) +SELECT date(created_at) as ordered_date, sum(price) as total_price +FROM orders +GROUP BY date(created_at) </sql> h3. Having @@ -555,7 +557,10 @@ Order.select("date(created_at) as ordered_date, sum(price) as total_price").grou The SQL that would be executed would be something like this: <sql> -SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) HAVING sum(price) > 100 +SELECT date(created_at) as ordered_date, sum(price) as total_price +FROM orders +GROUP BY date(created_at) +HAVING sum(price) > 100 </sql> This will return single order objects for each day, but only those that are ordered more than $100 in a day. @@ -829,7 +834,7 @@ SELECT categories.* FROM categories INNER JOIN posts ON posts.category_id = categories.id </sql> -Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:post).select("distinct(categories.id)"). +Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:posts).select("distinct(categories.id)"). h5. Joining Multiple Associations diff --git a/guides/source/configuring.textile b/guides/source/configuring.textile index 717654d5d8..1541428af9 100644 --- a/guides/source/configuring.textile +++ b/guides/source/configuring.textile @@ -525,6 +525,13 @@ development: password: </yaml> +If you use external connection pool manager, you can disable prepared statements in rails: +<yaml> +production: + adapter: postgresql + prepared_statements: false +</yaml> + h5. Configuring an SQLite3 Database for JRuby Platform If you choose to use SQLite3 and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section: diff --git a/guides/source/form_helpers.textile b/guides/source/form_helpers.textile index 8934667c5e..b6420db798 100644 --- a/guides/source/form_helpers.textile +++ b/guides/source/form_helpers.textile @@ -89,7 +89,7 @@ form_tag(:controller => "people", :action => "search", :method => "get", :class # => '<form accept-charset="UTF-8" action="/people/search?method=get&class=nifty_form" method="post">' </ruby> -Here, +method+ and +class+ are appended to the query string of the generated URL because you even though you mean to write two hashes, you really only specified one. So you need to tell Ruby which is which by delimiting the first hash (or both) with curly brackets. This will generate the HTML you expect: +Here, +method+ and +class+ are appended to the query string of the generated URL because even though you mean to write two hashes, you really only specified one. So you need to tell Ruby which is which by delimiting the first hash (or both) with curly brackets. This will generate the HTML you expect: <ruby> form_tag({:controller => "people", :action => "search"}, :method => "get", :class => "nifty_form") diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 59b12b49e5..f184004f80 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -10,7 +10,7 @@ you should be familiar with: endprologue. -WARNING. This Guide is based on Rails 3.1. Some of the code shown here will not +WARNING. This Guide is based on Rails 3.2. Some of the code shown here will not work in earlier versions of Rails. WARNING: The Edge version of this guide is currently being re-worked. Please excuse us while we re-arrange the place. @@ -27,8 +27,8 @@ prerequisites installed: TIP: Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails 3.0. Ruby Enterprise Edition have these fixed since release 1.8.7-2010.02 though. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults -on Rails 3.0, so if you want to use Rails 3 with 1.9.x jump on 1.9.2 for smooth -sailing. +on Rails 3.0, so if you want to use Rails 3 with 1.9.x jump on 1.9.2 or +1.9.3 for smooth sailing. * The "RubyGems":http://rubyforge.org/frs/?group_id=126 packaging system ** If you want to learn more about RubyGems, please read the "RubyGems User Guide":http://docs.rubygems.org/read/book/1 @@ -73,7 +73,8 @@ h3. Creating a New Rails Project The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can -literally follow along step by step. You can get the complete code "here":https://github.com/lifo/docrails/tree/master/guides/code/getting_started. +literally follow along step by step. You can get the complete code +"here":https://github.com/lifo/docrails/tree/master/guides/code/getting_started. By following along with this guide, you'll create a Rails project called <tt>blog</tt>, a (very) simple weblog. Before you can start building the application, you need to @@ -97,7 +98,7 @@ To verify that you have everything installed correctly, you should be able to ru $ rails --version </shell> -If it says something like "Rails 3.2.2" you are ready to continue. +If it says something like "Rails 3.2.3" you are ready to continue. h4. Creating the Blog Application @@ -111,7 +112,7 @@ $ rails new blog This will create a Rails application called Blog in a directory called blog. -TIP: You can see all of the switches that the Rails application builder accepts by running <tt>rails new -h</tt>. +TIP: You can see all of the command line options that the Rails application builder accepts by running <tt>rails new -h</tt>. After you create the blog application, switch to its folder to continue work directly in that application: @@ -225,7 +226,6 @@ h4. Laying down the ground work The first thing that you are going to need to create a new post within the application is a place to do that. A great place for that would be at +/posts/new+. If you attempt to navigate to that now -- by visiting "http://localhost:3000/posts/new":http://localhost:3000/posts/new -- Rails will give you a routing error: - !images/getting_started/routing_error_no_route_matches.png(A routing error, no route matches /posts/new)! This is because there is nowhere inside the routes for the application -- defined inside +config/routes.rb+ -- that defines this route. By default, Rails has no routes configured at all, and so you must define your routes as you need them. @@ -240,7 +240,7 @@ This route is a super-simple route: it defines a new route that only responds to With the route defined, requests can now be made to +/posts/new+ in the application. Navigate to "http://localhost:3000/posts/new":http://localhost:3000/posts/new and you'll see another routing error: -!images/getting_started/routing_error_no_controller.png(Another routing error, uninitialized constant PostsController) +!images/getting_started/routing_error_no_controller.png(Another routing error, uninitialized constant PostsController)! This error is happening because this route need a controller to be defined. The route is attempting to find that controller so it can serve the request, but with the controller undefined, it just can't do that. The solution to this particular problem is simple: you need to create a controller called +PostsController+. You can do this by running this command: @@ -259,7 +259,7 @@ A controller is simply a class that is defined to inherit from +ApplicationContr If you refresh "http://localhost:3000/posts/new":http://localhost:3000/posts/new now, you'll get a new error: -!images/getting_started/unknown_action_new_for_posts.png(Unknown action new for PostsController!) +!images/getting_started/unknown_action_new_for_posts.png(Unknown action new for PostsController!)! This error indicates that Rails cannot find the +new+ action inside the +PostsController+ that you just generated. This is because when controllers are generated in Rails they are empty by default, unless you tell it you wanted actions during the generation process. @@ -272,7 +272,7 @@ end With the +new+ method defined in +PostsController+, if you refresh "http://localhost:3000/posts/new":http://localhost:3000/posts/new you'll see another error: -!images/getting_started/template_is_missing_posts_new.png(Template is missing for posts/new) +!images/getting_started/template_is_missing_posts_new.png(Template is missing for posts/new)! You're getting this error now because Rails expects plain actions like this one to have views associated with them to display their information. With no view available, Rails errors out. @@ -302,7 +302,9 @@ When you refresh "http://localhost:3000/posts/new":http://localhost:3000/posts/n h4. The first form -To create a form within this template, you will use a _form builder_. The primary form builder for Rails is provided by a helper method called +form_for+. To use this method, write this code into +app/views/posts/new.html.erb+: +To create a form within this template, you will use a <em>form +builder</em>. The primary form builder for Rails is provided by a helper +method called +form_for+. To use this method, add this code into +app/views/posts/new.html.erb+: <erb> <%= form_for :post do |f| %> @@ -346,7 +348,7 @@ By using the +post+ method rather than the +get+ method, Rails will define a rou With the form and the route for it defined now, you will be able to fill in the form and then click the submit button to begin the process of creating a new post, so go ahead and do that. When you submit the form, you should see a familiar error: -!images/getting_started/unknown_action_create_for_posts(Unknown action create for PostsController)! +!images/getting_started/unknown_action_create_for_posts.png(Unknown action create for PostsController)! You will now need to create the +create+ action within the +PostsController+ for this to work. @@ -385,10 +387,30 @@ If you re-submit the form one more time you'll now no longer get the missing tem This action is now displaying the parameters for the post that are coming in from the form. However, this isn't really all that helpful. Yes, you can see the parameters but nothing in particular is being done with them. +h4. Creating the Post model + +Rails uses models to manage database objects, so if you want to save +data to the database you'll have to create a model. In our blog +application you want to save posts, so you'll create a +Post+ model. + +You can create a model with the following command: + +<shell> +$ rails generate model Post title:string text:text +</shell> + +With that command we told Rails that we want a +Post+ model, which in +turn should have a title attribute of type string, and a text attribute +of type text. Rails in turn responded by creating a bunch of files. For +now, we're only interested in +app/models/post.rb+ and ++db/migrate/20120419084633_create_posts.rb+. The latter is responsible +for creating the dabase structure, which is what we'll look at next. + h4. Running a Migration -One of the products of the +rails generate scaffold+ command is a _database -migration_. Migrations are Ruby classes that are designed to make it simple to +As we've just seen, +rails generate model+ created a _database +migration_ file inside the +db/migrate+ directory. +Migrations are Ruby classes that are designed to make it simple to create and modify database tables. Rails uses rake commands to run migrations, and it's possible to undo a migration after it's been applied to your database. Migration filenames include a timestamp to ensure that they're processed in the @@ -401,9 +423,8 @@ yours will have a slightly different name), here's what you'll find: class CreatePosts < ActiveRecord::Migration def change create_table :posts do |t| - t.string :name t.string :title - t.text :content + t.text :text t.timestamps end @@ -415,7 +436,7 @@ The above migration creates a method named +change+ which will be called when yo run this migration. The action defined in this method is also reversible, which means Rails knows how to reverse the change made by this migration, in case you want to reverse it later. When you run this migration it will create a -+posts+ table with two string columns and a text column. It also creates two ++posts+ table with one string column and a text column. It also creates two timestamp fields to allow Rails to track post creation and update times. More information about Rails migrations can be found in the "Rails Database Migrations":migrations.html guide. @@ -442,39 +463,203 @@ command will apply to the database defined in the +development+ section of your environment, for instance in production, you must explicitly pass it when invoking the command: <tt>rake db:migrate RAILS_ENV=production</tt>. -h4. Adding a Link +h4. Saving data in the controller + +Back into +posts_controller+, we need to change the +create+ action +to use the new +Post+ model to save data in the database. Open that file +and change the +create+ action to look like the following: + +<ruby> +def create + @post = Post.new(params[:post]) + + @post.save + redirect_to :action => :show, :id => @post.id +end +</ruby> + +Here's what's going on: every Rails model can be initialized with its +respective attributes, which are automatically mapped to its +database columns. In the first line we do just that (remember that ++params[:post]+ contains the attributes we're interested in). Then, ++@post.save+ is responsible for saving the model in the database. +Finally, on the last line we redirect the user to the +show+ action, +wich we have not defined yet. -To hook the posts up to the home page you've already created, you can add a link -to the home page. Open +app/views/welcome/index.html.erb+ and modify it as follows: +TIP: As we'll see later, +@post.save+ returns a boolean indicating +wherever the model was saved or not, and you can (and usually do) take +different actions depending on the result of calling +@post.save+. + +h4. Showing posts + +Before trying to create a new post, let's add the +show+ action, which +will be responsible for showing our posts. Open +config/routes.rb+ +and add the following route: + +<ruby> +get "posts/:id" => "posts#show" +</ruby> + +The special syntax +:id+ tells rails that this route expects an +:id+ +parameter, which in our case will be the id of the post. Note that this +time we had to specify the actual mapping, +posts#show+ because +otherwise Rails would not know which action to render. + +As we did before, we need to add the +show+ action in the ++posts_controller+ and its respective view. + +<ruby> +def show + @post = Post.find(params[:id]) +end +</ruby> + +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 +variables to the view. + +Now, create a new file +app/view/posts/show.html.erb+ with the following +content: + +<erb> +<p> + <strong>Title:</strong> + <%= @post.title %> +</p> + +<p> + <strong>Text:</strong> + <%= @post.text %> +</p> +</erb> + +Finally, if you now go to +"http://localhost:3000/posts/new":http://localhost:3000/posts/new you'll +be able to create a post. Try it! + +!images/getting_started/show_action_for_posts.png(Show action for posts)! + +h4. Listing all posts + +We still need a way to list all our posts, so let's do that. As usual, +we'll need a route, a controller action, and a view: + +<ruby> +# Add to config/routes.rb +get "posts" => "posts#index" + +# Add to app/controllers/posts_controller.rb +def index + @posts = Post.all +end +</ruby> + ++app/view/posts/index.html.erb+: + +<erb> +<h1>Listing posts</h1> + +<table> + <tr> + <th>Title</th> + <th>Text</th> + </tr> + +<% @posts.each do |post| %> + <tr> + <td><%= post.title %></td> + <td><%= post.text %></td> + </tr> +<% end %> +</table> +</erb> + +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. + +Open +app/views/welcome/index.html.erb+ and modify it as follows: <ruby> <h1>Hello, Rails!</h1> -<%= link_to "My Blog", posts_path %> +<%= link_to "My Blog", :controller => "posts" %> </ruby> The +link_to+ method is one of Rails' built-in view helpers. It creates a hyperlink based on text to display and where to go - in this case, to the path for posts. -h4. Working with Posts in the Browser +Let's add links to the other views as well. -Now you're ready to start working with posts. To do that, navigate to -"http://localhost:3000":http://localhost:3000/ and then click the "My Blog" -link: +<erb> +# app/views/posts/index.html.erb -!images/posts_index.png(Posts Index screenshot)! +<h1>Listing posts</h1> -This is the result of Rails rendering the +index+ view of your posts. There -aren't currently any posts in the database, but if you click the +New Post+ link -you can create one. After that, you'll find that you can edit posts, look at -their details, or destroy them. All of the logic and HTML to handle this was -built by the single +rails generate scaffold+ command. +<%= link_to 'New post', :action => :new %> + +<table> + <tr> + <th>Title</th> + <th>Text</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> + </tr> +<% end %> +</table> + +# 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 %> + +# app/views/posts/show.html.erb + +<p> + <strong>Title:</strong> + <%= @post.title %> +</p> + +<p> + <strong>Text:</strong> + <%= @post.text %> +</p> + +<%= link_to 'Back', :action => :index %> +</erb> + +TIP: If you want to link to an action in the same controller, you don't +need to specify the +:controller+ option, as Rails will use the current +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. +Congratulations, you're riding the rails! Now it’s time to see how it all works. h4. The Model @@ -498,17 +683,102 @@ Open the +app/models/post.rb+ file and edit it: <ruby> class Post < ActiveRecord::Base - validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 } end </ruby> -These changes will ensure that all posts have a name and a title, and that the -title is at least five characters long. Rails can validate a variety of -conditions in a model, including the presence or uniqueness of columns, their +These changes will ensure that all posts have a title that is at least five characters long. +Rails can validate a variety of conditions in a model, including the presence or uniqueness of columns, their format, and the existence of associated objects. Validations are covered in detail -in "Active Record Validations and Callbacks":active_record_validations_callbacks.html#validations-overview +in "Active Record Validations and +Callbacks":active_record_validations_callbacks.html#validations-overview + +If you open +posts_controller+ again, you'll notice that we don't check +the result of calling +@post.save+. We need to change its behavior to +show the form back to the user if any error occur: + +<ruby> +def new + @post = Post.new +end + +def create + @post = Post.new(params[:post]) + + if @post.save + redirect_to :action => :show, :id => @post.id + else + render 'new' + end +end +</ruby> + +Notice that I've also added +@post = Post.new+ to the +new+ action. I'll +explain why I did that in the next section, for now add that to your +controller as well. + +Also notice that we use +render+ instead of +redirect_to+ when +save+ +returns false. We can use +render+ so that the +@post+ object is passed +back to the view. + +If you reload +"http://localhost:3000/posts/new":http://localhost:3000/posts/new and +try to save a post without a title, Rails will send you back to the +form, but that's not very useful. You need to tell the user that +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| %> + <% 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> + +A few things are going on. We check if there are any errors with ++@post.errors.any?+, and in that case we show a list of all +errors with +@post.errors.full_messages+. + ++pluralize+ is a rails helper +that takes a number and a string as its arguments. If the number is +greater than one, the string will be automatically pluralized. + +The reason why we added +@post = Post.new+ in +posts_controller+ is that +otherwise +@post+ would be +nil+ in our view, and calling ++@post.errors.any?+ would throw an error. + +TIP: Rails automatically wraps fields that contain an error with a div +with class +field_with_errors+. You can define a css rule to make them +standout. + +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. Using the Console diff --git a/guides/source/migrations.textile b/guides/source/migrations.textile index f663496854..f855072fd8 100644 --- a/guides/source/migrations.textile +++ b/guides/source/migrations.textile @@ -82,6 +82,8 @@ it to default to +false+ for new users, but existing users are considered to have already opted in, so we use the User model to set the flag to +true+ for existing users. +h4. Using the change method + Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when @@ -475,7 +477,16 @@ end </ruby> will add an +attachment_id+ column and a string +attachment_type+ column with -a default value of 'Photo'. +a default value of 'Photo'. +references+ also allows you to define an +index directly, instead of using +add_index+ after the +create_table+ call: + +<ruby> +create_table :products do |t| + t.references :category, :index => true +end +</ruby> + +will create an index identical to calling `add_index :products, :category_id`. NOTE: The +references+ helper does not actually create foreign key constraints for you. You will need to use +execute+ or a plugin that adds "foreign key @@ -770,7 +781,7 @@ Both migrations work for Alice. Bob comes back from vacation and: -# Updates the source - which contains both migrations and the latests version of +# Updates the source - which contains both migrations and the latest version of the Product model. # Runs outstanding migrations with +rake db:migrate+, which includes the one that updates the +Product+ model. 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/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.rb b/railties/lib/rails/generators.rb index b9c1b01f54..55642f8140 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -52,6 +52,7 @@ module Rails :orm => false, :performance_tool => nil, :resource_controller => :controller, + :resource_route => true, :scaffold_controller => :scaffold_controller, :stylesheets => true, :stylesheet_engine => :css, @@ -172,6 +173,7 @@ module Rails [ "rails", + "resource_route", "#{orm}:migration", "#{orm}:model", "#{orm}:observer", diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index bb2a9fcf22..8c8ed5010f 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -120,7 +120,7 @@ module Rails end def database_gemfile_entry - options[:skip_active_record] ? "" : "gem '#{gem_for_database}'\n" + options[:skip_active_record] ? "" : "gem '#{gem_for_database}'" end def include_all_railties? @@ -137,12 +137,14 @@ module Rails gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}' gem 'journey', :git => 'https://github.com/rails/journey.git' gem 'arel', :git => 'https://github.com/rails/arel.git' + gem 'active_record_deprecated_finders', :git => 'git://github.com/rails/active_record_deprecated_finders.git' GEMFILE elsif options.edge? <<-GEMFILE.strip_heredoc gem 'rails', :git => 'https://github.com/rails/rails.git' gem 'journey', :git => 'https://github.com/rails/journey.git' gem 'arel', :git => 'https://github.com/rails/arel.git' + gem 'active_record_deprecated_finders', :git => 'git://github.com/rails/active_record_deprecated_finders.git' GEMFILE else <<-GEMFILE.strip_heredoc diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb index 67f263efbb..e15c963971 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb @@ -2,7 +2,7 @@ <% attributes.each do |attribute| -%> <p> - <b><%= attribute.human_name %>:</b> + <strong><%= attribute.human_name %>:</strong> <%%= @<%= singular_table_name %>.<%= attribute.name %> %> </p> diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb index 7dfc1aa599..25d0161e4c 100644 --- a/railties/lib/rails/generators/generated_attribute.rb +++ b/railties/lib/rails/generators/generated_attribute.rb @@ -1,6 +1,4 @@ require 'active_support/time' -require 'active_support/core_ext/object/inclusion' -require 'active_support/core_ext/object/blank' module Rails module Generators @@ -21,9 +19,20 @@ module Rails has_index, type = type, nil if INDEX_OPTIONS.include?(type) type, attr_options = *parse_type_and_options(type) + type = type.to_sym if type + + if type && reference?(type) + references_index = UNIQ_INDEX_OPTIONS.include?(has_index) ? { :unique => true } : true + attr_options[:index] = references_index + end + new(name, type, has_index, attr_options) end + def reference?(type) + [:references, :belongs_to].include? type + end + private # parse possible attribute options like :limit for string/text/binary/integer or :precision/:scale for decimals @@ -42,7 +51,7 @@ module Rails def initialize(name, type=nil, index_type=false, attr_options={}) @name = name - @type = (type.presence || :string).to_sym + @type = type || :string @has_index = INDEX_OPTIONS.include?(index_type) @has_uniq_index = UNIQ_INDEX_OPTIONS.include?(index_type) @attr_options = attr_options @@ -87,7 +96,7 @@ module Rails end def reference? - self.type.in?(:references, :belongs_to) + self.class.reference?(type) end def has_index? diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 676662b9f5..bf47e66cc4 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -22,4 +22,4 @@ source 'https://rubygems.org' # gem 'capistrano', :group => :development # To use debugger -# gem 'ruby-debug19', :require => 'ruby-debug' +# gem 'debugger' diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 7b2c86db24..1c980e5ce6 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -32,8 +32,8 @@ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # See everything in the log (default is :info). - # config.log_level = :debug + # Set to :debug to see everything in the log. + config.log_level = :info # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] 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 ea81748464..24026cf324 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb @@ -3,11 +3,11 @@ # first created -> highest priority. # Sample of regular route: - # match 'products/:id' => 'catalog#view' + # get 'products/:id' => 'catalog#view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: - # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase + # get 'products/:id/purchase' => 'catalog#purchase', :as => :purchase # This route can be invoked with purchase_url(:id => product.id) # Sample resource route (maps HTTP verbs to controller actions automatically): @@ -52,7 +52,4 @@ # See how all your routes lay out with "rake routes" - # This is a legacy wild controller route that's not recommended for RESTful applications. - # Note: This route will make all actions in every controller accessible via GET requests. - # match ':controller(/:action(/:id))(.:format)' end diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb index 7c7b289d19..3a0586ee43 100644 --- a/railties/lib/rails/generators/rails/resource/resource_generator.rb +++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb @@ -14,16 +14,7 @@ module Rails class_option :actions, :type => :array, :banner => "ACTION ACTION", :default => [], :desc => "Actions for the resource controller" - class_option :http, :type => :boolean, :default => false, - :desc => "Generate resource with HTTP actions only" - - def add_resource_route - return if options[:actions].present? - route_config = regular_class_path.collect{ |namespace| "namespace :#{namespace} do " }.join(" ") - route_config << "resources :#{file_name.pluralize}" - route_config << " end" * regular_class_path.size - route route_config - end + hook_for :resource_route, :required => true end end end diff --git a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb new file mode 100644 index 0000000000..6a5d62803c --- /dev/null +++ b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb @@ -0,0 +1,13 @@ +module Rails + module Generators + class ResourceRouteGenerator < NamedBase + def add_resource_route + return if options[:actions].present? + route_config = regular_class_path.collect{ |namespace| "namespace :#{namespace} do " }.join(" ") + route_config << "resources :#{file_name.pluralize}" + route_config << " end" * regular_class_path.size + route route_config + end + end + end +end diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb index 083eb49d65..0618b16984 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb @@ -10,9 +10,6 @@ module Rails class_option :orm, :banner => "NAME", :type => :string, :required => true, :desc => "ORM to generate the controller for" - class_option :http, :type => :boolean, :default => false, - :desc => "Generate controller with HTTP actions only" - def create_controller_files template "controller.rb", File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb") end diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb index 9e76587a0d..ca7fee3b6e 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb @@ -10,9 +10,6 @@ module TestUnit argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" - class_option :http, :type => :boolean, :default => false, - :desc => "Generate functional test with HTTP actions only" - def create_test_files template "functional_test.rb", File.join("test/functional", controller_class_path, "#{controller_file_name}_controller_test.rb") diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 4cd60fdc39..a443c73962 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -30,8 +30,9 @@ class SourceAnnotationExtractor # Prints all annotations with tag +tag+ under the root directories +app+, +config+, +lib+, # +script+, and +test+ (recursively). Only filenames with extension - # +.builder+, +.rb+, and +.erb+ are taken into account. The +options+ - # hash is passed to each annotation's +to_s+. + # +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+, +.scss+, +.js+, and + # +.coffee+ are taken into account. The +options+ hash is passed to each + # annotation's +to_s+. # # This class method is the single entry point for the rake tasks. def self.enumerate(tag, options={}) @@ -53,7 +54,8 @@ class SourceAnnotationExtractor # Returns a hash that maps filenames under +dir+ (recursively) to arrays # with their annotations. Only files with annotations are included, and only - # those with extension +.builder+, +.rb+, +.erb+, +.haml+, +.slim+ and +.coffee+ + # those with extension +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+, + # +.scss+, +.js+, and +.coffee+ # are taken into account. def find_in(dir) results = {} @@ -65,6 +67,8 @@ class SourceAnnotationExtractor results.update(find_in(item)) elsif item =~ /\.(builder|rb|coffee)$/ results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/)) + elsif item =~ /\.(css|scss|js)$/ + results.update(extract_annotations_from(item, /\/\/\s*(#{tag}):?\s*(.*)$/)) elsif item =~ /\.erb$/ results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/)) elsif item =~ /\.haml$/ diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake index 2851ca4189..4ec49eee76 100644 --- a/railties/lib/rails/tasks/documentation.rake +++ b/railties/lib/rails/tasks/documentation.rake @@ -2,7 +2,7 @@ require 'rdoc/task' # Monkey-patch to remove redoc'ing and clobber descriptions to cut down on rake -T noise class RDocTaskWithoutDescriptions < RDoc::Task - include ::Rake::DSL + include ::Rake::DSL if defined?(::Rake::DSL) def define task rdoc_task_name 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 a80898092d..d1a614e181 100644 --- a/railties/test/application/middleware/exceptions_test.rb +++ b/railties/test/application/middleware/exceptions_test.rb @@ -17,31 +17,32 @@ module ApplicationTests end test "show exceptions middleware filter backtrace before logging" do - my_middleware = Struct.new(:app) do - def call(env) - raise "Failure" + controller :foo, <<-RUBY + class FooController < ActionController::Base + def index + raise 'oops' + end end - end - - app.config.middleware.use my_middleware + RUBY - stringio = StringIO.new - Rails.logger = Logger.new(stringio) + get "/foo" + assert_equal 500, last_response.status - get "/" - assert_no_match(/action_dispatch/, stringio.string) + log = File.read(Rails.application.config.paths["log"].first) + assert_no_match(/action_dispatch/, log, log) + assert_match(/oops/, log, log) end test "renders active record exceptions as 404" do - my_middleware = Struct.new(:app) do - def call(env) - raise ActiveRecord::RecordNotFound + controller :foo, <<-RUBY + class FooController < ActionController::Base + def index + raise ActiveRecord::RecordNotFound + end end - end - - app.config.middleware.use my_middleware + RUBY - get "/" + get "/foo" assert_equal 404, last_response.status end @@ -104,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/middleware_test.rb b/railties/test/application/middleware_test.rb index fc5fb60174..ba747bc633 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -148,6 +148,13 @@ module ApplicationTests assert_equal "Rack::Config", middleware.first end + test "can't change middleware after it's built" do + boot! + assert_raise RuntimeError do + app.config.middleware.use Rack::Config + end + end + # ConditionalGet + Etag test "conditional get + etag middlewares handle http caching based on body" do make_basic_app diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 04abf9e3a1..d069703d30 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -17,6 +17,9 @@ module ApplicationTests app_file "app/views/home/index.html.haml", "-# TODO: note in haml" app_file "app/views/home/index.html.slim", "/ TODO: note in slim" app_file "app/assets/javascripts/application.js.coffee", "# TODO: note in coffee" + app_file "app/assets/javascripts/application.js", "// TODO: note in js" + app_file "app/assets/stylesheets/application.css", "// TODO: note in css" + app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby" boot_rails @@ -35,8 +38,11 @@ module ApplicationTests assert_match /note in slim/, output assert_match /note in ruby/, output assert_match /note in coffee/, output + assert_match /note in js/, output + assert_match /note in css/, output + assert_match /note in scss/, output - assert_equal 5, lines.size + assert_equal 8, lines.size lines.each do |line| assert_equal 4, line[0].size 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/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 40cb876b34..ef6877ed30 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -294,10 +294,10 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_inclusion_of_ruby_debug19 + def test_inclusion_of_debugger run_generator assert_file "Gemfile" do |contents| - assert_match(/gem 'ruby-debug19', :require => 'ruby-debug'/, contents) + assert_match(/gem 'debugger'/, contents) end end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index e8d933935d..fd3b8c8a17 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -283,7 +283,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_match(/add_index/, up) + assert_match(/index: true/, up) end end end @@ -293,7 +293,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_match(/add_index/, up) + assert_match(/index: true/, up) end end end @@ -303,7 +303,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_no_match(/add_index/, up) + assert_no_match(/index: true/, up) end end end @@ -313,7 +313,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_no_match(/add_index/, up) + assert_no_match(/index: true/, up) end end end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 7123950add..9b456c64ef 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -14,10 +14,8 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/models/product_line.rb", /class ProductLine < ActiveRecord::Base/ assert_file "test/unit/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/ assert_file "test/fixtures/product_lines.yml" - assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product/ - assert_migration "db/migrate/create_product_lines.rb", /add_index :product_lines, :product_id/ - assert_migration "db/migrate/create_product_lines.rb", /references :user/ - assert_migration "db/migrate/create_product_lines.rb", /add_index :product_lines, :user_id/ + assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product, index: true/ + assert_migration "db/migrate/create_product_lines.rb", /references :user, index: true/ # Route assert_file "config/routes.rb" do |route| 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 |