From f73e9d2df8e40cdbf145995452f6e7c88b98c232 Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 2 Aug 2010 23:39:17 -0700 Subject: [PATCH 001/805] Properly deprecate `config.load_paths` and `config.gem` --- railties/lib/rails/engine/configuration.rb | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 521ed95..26b1a68 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -48,6 +48,33 @@ module Rails def autoload_paths @autoload_paths ||= paths.autoload_paths end + + def load_paths + ActiveSupport::Deprecation.warn "config.load_paths is deprecated. Please use config.autoload_paths instead." + autoload_paths + end + + def load_paths=(paths) + ActiveSupport::Deprecation.warn "config.load_paths= is deprecated. Please use config.autoload_paths instead." + self.autoload_paths = paths + end + + # Rails 3, by default, uses bundler, which shims the Kernel#gem method so that it should + # behave correctly for this deprecation. + def gem(name, options = {}) + super name, options[:version] || ">= 0" + require options[:lib] || name + rescue Gem::LoadError + msg = "config.gem is deprecated, and you tried to activate the '#{name}' gem using it.\n" + + if File.exist?("#{Rails.root}/Gemfile") + msg << "Please add '#{name}' to your Gemfile." + else + msg << "Please update your application to use bundler." + end + ActiveSupport::Deprecation.warn(msg, caller) + exit + end end end end -- 1.7.1 From a44779e9bb2b4af0ce6d0e77746e751c9b10d823 Mon Sep 17 00:00:00 2001 From: Samuel Lebeau Date: Tue, 3 Aug 2010 11:25:15 +0200 Subject: [PATCH 002/805] Avoid potentially expensive inspect call in router. [#4491 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../lib/action_dispatch/routing/route_set.rb | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 77688fe..d23b580 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -392,10 +392,9 @@ module ActionDispatch end def generate - error = ActionController::RoutingError.new("No route matches #{options.inspect}") path, params = @set.set.generate(:path_info, named_route, options, recall, opts) - raise error unless path + raise_routing_error unless path params.reject! {|k,v| !v } @@ -404,7 +403,7 @@ module ActionDispatch path << "?#{params.to_query}" if params.any? "#{script_name}#{path}" rescue Rack::Mount::RoutingError - raise error + raise_routing_error end def opts @@ -421,6 +420,10 @@ module ActionDispatch {:parameterize => parameterize} end + def raise_routing_error + raise ActionController::RoutingError.new("No route matches #{options.inspect}") + end + def different_controller? return false unless current_controller controller.to_param != current_controller.to_param -- 1.7.1 From 257e9c4ec46c5045785081e3989bed9bc8d9b37a Mon Sep 17 00:00:00 2001 From: rohit Date: Tue, 3 Aug 2010 16:28:55 +0530 Subject: [PATCH 003/805] Failing test for validates_length_of, when both too_short and too_long messages are set [#5283 state:open] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../cases/validations/length_validation_test.rb | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index 012c5a2..1e6180a 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -229,6 +229,20 @@ class LengthValidationTest < ActiveModel::TestCase assert_equal ["hoo 5"], t.errors["title"] end + def test_validates_length_of_custom_errors_for_both_too_short_and_too_long + Topic.validates_length_of :title, :minimum => 3, :maximum => 5, :too_short => 'too short', :too_long => 'too long' + + t = Topic.new(:title => 'a') + assert t.invalid? + assert t.errors[:title].any? + assert_equal ['too short'], t.errors['title'] + + t = Topic.new(:title => 'aaaaaa') + assert t.invalid? + assert t.errors[:title].any? + assert_equal ['too long'], t.errors['title'] + end + def test_validates_length_of_custom_errors_for_is_with_message Topic.validates_length_of( :title, :is=>5, :message=>"boo %{count}" ) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") -- 1.7.1 From 79583ca9b14d7c16e0118de27cd95a0fd6647791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 3 Aug 2010 15:22:54 +0200 Subject: [PATCH 004/805] validates_length_of should not change the options hash in place. [#5283 state:resolved] --- activemodel/lib/active_model/validations/length.rb | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index c8a77ad..a7af4f2 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -40,8 +40,6 @@ module ActiveModel CHECKS.each do |key, validity_check| next unless check_value = options[key] - default_message = options[MESSAGES[key]] - options[:message] ||= default_message if default_message valid_value = if key == :maximum value.nil? || value.size.send(validity_check, check_value) @@ -51,8 +49,13 @@ module ActiveModel next if valid_value - record.errors.add(attribute, MESSAGES[key], - options.except(*RESERVED_OPTIONS).merge!(:count => check_value)) + errors_options = options.except(*RESERVED_OPTIONS) + errors_options[:count] = check_value + + default_message = options[MESSAGES[key]] + errors_options[:message] ||= default_message if default_message + + record.errors.add(attribute, MESSAGES[key], errors_options) end end end -- 1.7.1 From 3b170b2e14aff7bf1d628356ab7f86b43ea46c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 3 Aug 2010 15:34:31 +0200 Subject: [PATCH 005/805] Freeze options so we raise an error when people modify it in place. --- activemodel/lib/active_model/validations.rb | 6 ++++-- activemodel/lib/active_model/validator.rb | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 1a58d4c..3407c59 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -118,11 +118,13 @@ module ActiveModel # end # def validate(*args, &block) - options = args.last - if options.is_a?(Hash) && options.key?(:on) + options = args.extract_options! + if options.key?(:on) + options = options.dup options[:if] = Array.wrap(options[:if]) options[:if] << "validation_context == :#{options[:on]}" end + args << options set_callback(:validate, *args, &block) end diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb index 52192d5..163124d 100644 --- a/activemodel/lib/active_model/validator.rb +++ b/activemodel/lib/active_model/validator.rb @@ -111,7 +111,7 @@ module ActiveModel #:nodoc: # Accepts options that will be made available through the +options+ reader. def initialize(options) - @options = options + @options = options.freeze end # Return the kind for this validator. -- 1.7.1 From 677e1e58b6c32b34a95d15ecd5ddb749d4158d30 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 3 Aug 2010 02:05:00 -0300 Subject: [PATCH 006/805] Stub is_a? not instance_of? here --- railties/test/generators/app_generator_test.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 21725a3..08cfb58 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -114,7 +114,7 @@ class AppGeneratorTest < Rails::Generators::TestCase Rails.application.config.root = app_moved_root Rails.application.class.stubs(:name).returns("Myapp") - Rails.application.stubs(:instance_of?).returns(Rails::Application) + Rails.application.stubs(:is_a?).returns(Rails::Application) FileUtils.mv(app_root, app_moved_root) -- 1.7.1 From 5987fd4c79a219753f0eafa0b57198f0a29387ca Mon Sep 17 00:00:00 2001 From: Subba Rao Pasupuleti Date: Tue, 3 Aug 2010 12:35:58 -0400 Subject: [PATCH 007/805] Tidy up error.rb code [#5288 state:committed] Signed-off-by: Santiago Pastorino --- activemodel/lib/active_model/errors.rb | 6 +----- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index f39678d..05e353c 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -86,11 +86,7 @@ module ActiveModel # p.errors[:name] # => ["can not be nil"] # p.errors['name'] # => ["can not be nil"] def [](attribute) - if errors = get(attribute.to_sym) - errors - else - set(attribute.to_sym, []) - end + get(attribute.to_sym) || set(attribute.to_sym, []) end # Adds to the supplied attribute the supplied error message. -- 1.7.1 From 1318bf6e33fe07bcc9fe50854b0bbb4627e71e88 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 11:47:19 -0700 Subject: [PATCH 008/805] Properly deprecate validate_on_#{on} --- activemodel/lib/active_model/validations.rb | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 3407c59..32e3cb5 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -128,6 +128,18 @@ module ActiveModel set_callback(:validate, *args, &block) end + [:create, :update].each do |type| + class_eval <<-RUBY + def validate_on_#{type}(*args, &block) + msg = "validate_on_#{type} is deprecated. Please use validate(args, :on => :#{type})" + ActiveSupport::Deprecation.warn(msg, caller) + options = args.last || {} + options[:on] = :#{type} + validate(args.push(options), &block) + end + RUBY + end + # List all validators that are being used to validate the model using # +validates_with+ method. def validators -- 1.7.1 From 9ae7f04cd6c1cdbdd6454448b25302b584860ef6 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 11:47:57 -0700 Subject: [PATCH 009/805] properly deprecate #{type}_validation_on_#{on} --- .../lib/active_model/validations/callbacks.rb | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb index afd65d3..f46593b 100644 --- a/activemodel/lib/active_model/validations/callbacks.rb +++ b/activemodel/lib/active_model/validations/callbacks.rb @@ -44,6 +44,20 @@ module ActiveModel options[:if] << "self.validation_context == :#{options[:on]}" if options[:on] set_callback(:validation, :after, *(args << options), &block) end + + [:before, :after].each do |type| + [:create, :update].each do |on| + class_eval <<-RUBY + def #{type}_validation_on_#{on}(*args, &block) + msg = "#{type}_validation_on_#{on} is deprecated. Please use #{type}_validation(arguments, :on => :#{on}" + ActiveSupport::Deprecation.warn(msg, caller) + options = args.extract_options! + options[:on] = :#{on} + before_validation(args.push(options), &block) + end + RUBY + end + end end protected -- 1.7.1 From 4474470ffda3d08c9469fe113e251ff3a9e8bd54 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 11:49:44 -0700 Subject: [PATCH 010/805] update this for a change in the core method --- activemodel/lib/active_model/validations.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 32e3cb5..14e6ca0 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -133,7 +133,7 @@ module ActiveModel def validate_on_#{type}(*args, &block) msg = "validate_on_#{type} is deprecated. Please use validate(args, :on => :#{type})" ActiveSupport::Deprecation.warn(msg, caller) - options = args.last || {} + options = args.extract_options! options[:on] = :#{type} validate(args.push(options), &block) end -- 1.7.1 From 7a1bba4799f3fae2c3699816bc071128fd591461 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 12:22:10 -0700 Subject: [PATCH 011/805] Allow :name to be a Symbol (was this removed by accident?) --- .../abstract/schema_statements.rb | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) 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 ffc3847..7dee685 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -327,6 +327,8 @@ module ActiveRecord # # Note: SQLite doesn't support index length def add_index(table_name, column_name, options = {}) + options[:name] = options[:name].to_s if options.key?(:name) + column_names = Array.wrap(column_name) index_name = index_name(table_name, :column => column_names) -- 1.7.1 From 01186652ccc546842591ebf6e1d42225797ec5d4 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 12:29:03 -0700 Subject: [PATCH 012/805] Even though exempt_from_layout is no longer needed, some people are still using it. Deprecate it instead of removing. --- .../lib/action_controller/deprecated/base.rb | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 3975afc..006d760 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -120,9 +120,14 @@ module ActionController # This was moved to a plugin def verify(*args) - ActiveSupport::Deprecation.warn "verify was removed from Rails and is now available as a plugin. " << + ActiveSupport::Deprecation.warn "verify was removed from Rails and is now available as a plugin. " \ "Please install it with `rails plugin install git://github.com/rails/verification.git`.", caller end + + def exempt_from_layout(*) + ActiveSupport::Deprecation.warn "exempt_from_layout is no longer needed, because layouts in Rails 3 " \ + "are restricted to the content-type of the template that was rendered.", caller + end end extend DeprecatedBehavior -- 1.7.1 From 43cc69cb6518ecae816c33513081236dd46702f3 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 12:31:39 -0700 Subject: [PATCH 013/805] Fix the session= deprecation to include the secret key --- .../lib/action_controller/deprecated/base.rb | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 006d760..4739eca 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -81,6 +81,11 @@ module ActionController def session=(value) ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << "Please configure it on your application with config.session_store :cookie_store, :key => '....'", caller + + if secret = value.delete(:secret) + Rails.application.config.secret_token = secret + end + if value.delete(:disabled) Rails.application.config.session_store :disabled else -- 1.7.1 From 84703be5ffe7d94fd33bfbdb45cb0bed72e0ab1f Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 12:41:18 -0700 Subject: [PATCH 014/805] Deprecate ActionController::UrlWriter properly --- actionpack/lib/action_controller.rb | 2 +- .../lib/action_controller/deprecated/url_writer.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletions(-) create mode 100644 actionpack/lib/action_controller/deprecated/url_writer.rb diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index ca0e5d6..b7250d1 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -35,10 +35,10 @@ module ActionController end autoload :Dispatcher, 'action_controller/deprecated/dispatcher' + autoload :UrlWriter, 'action_controller/deprecated/url_writer' autoload :Integration, 'action_controller/deprecated/integration_test' autoload :IntegrationTest, 'action_controller/deprecated/integration_test' autoload :PerformanceTest, 'action_controller/deprecated/performance_test' - autoload :UrlWriter, 'action_controller/deprecated' autoload :Routing, 'action_controller/deprecated' autoload :TestCase, 'action_controller/test_case' diff --git a/actionpack/lib/action_controller/deprecated/url_writer.rb b/actionpack/lib/action_controller/deprecated/url_writer.rb new file mode 100644 index 0000000..d901cb4 --- /dev/null +++ b/actionpack/lib/action_controller/deprecated/url_writer.rb @@ -0,0 +1,9 @@ +module ActionController + module UrlWriter + def self.included(klass) + ActiveSupport::Deprecation.warn "include ActionController::UrlWriter is deprecated. Instead, " \ + "include Rails.application.routes.url_helpers" + klass.class_eval { include Rails.application.routes.url_helpers } + end + end +end -- 1.7.1 From 146a013c425cf4883fa320ab685fb869dda03733 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 12:50:13 -0700 Subject: [PATCH 015/805] Fix a couple of mistaken deprecation solutions --- activemodel/lib/active_model/validations.rb | 2 +- .../lib/active_model/validations/callbacks.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 14e6ca0..2927654 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -135,7 +135,7 @@ module ActiveModel ActiveSupport::Deprecation.warn(msg, caller) options = args.extract_options! options[:on] = :#{type} - validate(args.push(options), &block) + validate(*args.push(options), &block) end RUBY end diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb index f46593b..554c542 100644 --- a/activemodel/lib/active_model/validations/callbacks.rb +++ b/activemodel/lib/active_model/validations/callbacks.rb @@ -28,7 +28,7 @@ module ActiveModel module ClassMethods def before_validation(*args, &block) - options = args.last + options = args.extract_options! if options.is_a?(Hash) && options[:on] options[:if] = Array.wrap(options[:if]) options[:if] << "self.validation_context == :#{options[:on]}" @@ -53,7 +53,7 @@ module ActiveModel ActiveSupport::Deprecation.warn(msg, caller) options = args.extract_options! options[:on] = :#{on} - before_validation(args.push(options), &block) + before_validation(*args.push(options), &block) end RUBY end -- 1.7.1 From af8e08519008c545acd94f05ca1041885a934fba Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 12:50:41 -0700 Subject: [PATCH 016/805] Move the deprecations before the load hooks --- actionpack/lib/action_controller/base.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 9dfffce..f6920f1 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -63,8 +63,8 @@ module ActionController klass.helper :all end + require "action_controller/deprecated/base" ActiveSupport.run_load_hooks(:action_controller, self) end end -require "action_controller/deprecated/base" -- 1.7.1 From 109dc3c39cd7b1294320c8a9cc62f98ed0c85d91 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 14:23:46 -0700 Subject: [PATCH 017/805] Deprecate the @controller instance variable --- actionpack/lib/action_view/base.rb | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 20a2e7c..0e3abff 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -227,6 +227,7 @@ module ActionView #:nodoc: @lookup_context = lookup_context.is_a?(ActionView::LookupContext) ? lookup_context : ActionView::LookupContext.new(lookup_context) @lookup_context.formats = formats if formats + @controller = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :controller) end def controller_path -- 1.7.1 From 8b7219b9d6930dfd906e3dc1f4d9a84b904e7c4c Mon Sep 17 00:00:00 2001 From: RainerBlessing Date: Tue, 3 Aug 2010 20:37:46 +0200 Subject: [PATCH 018/805] query value is converted to_s instead of to_yaml --- .../connection_adapters/abstract/quoting.rb | 2 +- activerecord/test/cases/finder_test.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb index d7b5bf8..e2b3773 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb @@ -30,7 +30,7 @@ module ActiveRecord if value.acts_like?(:date) || value.acts_like?(:time) "'#{quoted_date(value)}'" else - "'#{quote_string(value.to_yaml)}'" + "'#{quote_string(value.to_s)}'" end end end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index a107c1a..4f3e43d 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -693,6 +693,14 @@ class FinderTest < ActiveRecord::TestCase assert_equal [], Topic.find_all_by_title("The First Topic!!") end + def test_find_all_by_one_attribute_which_is_a_symbol + topics = Topic.find_all_by_content("Have a nice day".to_sym) + assert_equal 2, topics.size + assert topics.include?(topics(:first)) + + assert_equal [], Topic.find_all_by_title("The First Topic!!") + end + def test_find_all_by_one_attribute_that_is_an_aggregate balance = customers(:david).balance assert_kind_of Money, balance -- 1.7.1 From 46a1da7c799c6c519e646089fe8df2935d4062d2 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 14:54:28 -0700 Subject: [PATCH 019/805] Put lib back on the autoload path --- railties/lib/rails/engine/configuration.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 26b1a68..5a63cc3 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -20,7 +20,7 @@ module Rails paths.app.models "app/models", :eager_load => true paths.app.mailers "app/mailers", :eager_load => true paths.app.views "app/views" - paths.lib "lib", :load_path => true + paths.lib "lib", :eager_load => true paths.lib.tasks "lib/tasks", :glob => "**/*.rake" paths.config "config" paths.config.initializers "config/initializers", :glob => "**/*.rb" -- 1.7.1 From b46b5a6d54a30d6000e9edc11a20c9248301715d Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 3 Aug 2010 16:03:35 -0700 Subject: [PATCH 020/805] Fix up constant deprecation to be less dependent on load order --- railties/lib/rails/deprecation.rb | 73 ++++++++++--------------------------- 1 files changed, 19 insertions(+), 54 deletions(-) diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb index 1eb6d80..924701a 100644 --- a/railties/lib/rails/deprecation.rb +++ b/railties/lib/rails/deprecation.rb @@ -1,62 +1,27 @@ require "active_support/string_inquirer" -require "active_support/deprecation" +require "active_support/basic_object" -RAILS_ROOT = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) do - cattr_accessor :warned - self.warned = false - - def target - Rails.root - end - - def replace(*args) - warn(caller, :replace, *args) - end - - def warn(callstack, called, args) - unless warned - ActiveSupport::Deprecation.warn("RAILS_ROOT is deprecated! Use Rails.root instead", callstack) - self.warned = true +module Rails + class DeprecatedConstant < ActiveSupport::BasicObject + def self.deprecate(old, new) + constant = self.new(old, new) + eval "::#{old} = constant" end - end -end).new - -RAILS_ENV = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) do - cattr_accessor :warned - self.warned = false - - def target - Rails.env - end - def replace(*args) - warn(caller, :replace, *args) - end - - def warn(callstack, called, args) - unless warned - ActiveSupport::Deprecation.warn("RAILS_ENV is deprecated! Use Rails.env instead", callstack) - self.warned = true + def initialize(old, new) + @old, @new = old, new + @target = eval "proc { #{new} }" + @warned = false end - end -end).new -RAILS_DEFAULT_LOGGER = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) do - cattr_accessor :warned - self.warned = false - - def target - Rails.logger - end - - def replace(*args) - warn(caller, :replace, *args) - end - - def warn(callstack, called, args) - unless warned - ActiveSupport::Deprecation.warn("RAILS_DEFAULT_LOGGER is deprecated! Use Rails.logger instead", callstack) - self.warned = true + def method_missing(meth, *args, &block) + ActiveSupport::Deprecation.warn("#{@old} is deprecated. Please use #{@new}") unless @warned + @warned = true + @target.call.send(meth, *args, &block) end end -end).new + + DeprecatedConstant.deprecate("RAILS_ROOT", "Rails.root") + DeprecatedConstant.deprecate("RAILS_ENV", "Rails.env") + DeprecatedConstant.deprecate("RAILS_DEFAULT_LOGGER", "Rails.logger") +end -- 1.7.1 From 9269e55b1f2e605ebde6717403f275a415b34974 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 3 Aug 2010 17:57:36 -0700 Subject: [PATCH 021/805] avoid passing AR::Base objects to Arel when we can --- .../lib/active_record/relation/finder_methods.rb | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index a192e04..bad9af2 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -169,6 +169,8 @@ module ActiveRecord # Person.exists?(['name LIKE ?', "%#{query}%"]) # Person.exists? def exists?(id = nil) + id = id.id if ActiveRecord::Base === id + case id when Array, Hash where(id).exists? -- 1.7.1 From 8158afa47ebe8c2f33cce72b71cb82cb97af0431 Mon Sep 17 00:00:00 2001 From: rohit Date: Wed, 4 Aug 2010 08:56:47 +0530 Subject: [PATCH 022/805] Give extracted options back to args in AMo callbacks. Fixes two failing tests in AR. Signed-off-by: Santiago Pastorino --- .../lib/active_model/validations/callbacks.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb index 554c542..24f0e7a 100644 --- a/activemodel/lib/active_model/validations/callbacks.rb +++ b/activemodel/lib/active_model/validations/callbacks.rb @@ -33,7 +33,7 @@ module ActiveModel options[:if] = Array.wrap(options[:if]) options[:if] << "self.validation_context == :#{options[:on]}" end - set_callback(:validation, :before, *args, &block) + set_callback(:validation, :before, *(args << options), &block) end def after_validation(*args, &block) -- 1.7.1 From 07c5e5416be3dbd53ffc502724435b0dc95fd0ef Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 01:07:11 -0700 Subject: [PATCH 023/805] Shim Initializer.run --- railties/lib/rails/deprecation.rb | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb index 924701a..1765c80 100644 --- a/railties/lib/rails/deprecation.rb +++ b/railties/lib/rails/deprecation.rb @@ -2,6 +2,14 @@ require "active_support/string_inquirer" require "active_support/basic_object" module Rails + module Initializer + def self.run(&block) + klass = Class.new(Rails::Application) + klass.instance_exec(klass.config, &block) + klass.initialize! + end + end + class DeprecatedConstant < ActiveSupport::BasicObject def self.deprecate(old, new) constant = self.new(old, new) -- 1.7.1 From 91e4249c028469bc284e9ae97d8bafc4966ab18d Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 02:15:15 -0700 Subject: [PATCH 024/805] Provide a bit more information in the deprecation for config.gem --- railties/lib/rails/engine/configuration.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 5a63cc3..2d784c6 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -65,7 +65,7 @@ module Rails super name, options[:version] || ">= 0" require options[:lib] || name rescue Gem::LoadError - msg = "config.gem is deprecated, and you tried to activate the '#{name}' gem using it.\n" + msg = "config.gem is deprecated, and you tried to activate the '#{name}' gem (#{options.inspect}) using it.\n" if File.exist?("#{Rails.root}/Gemfile") msg << "Please add '#{name}' to your Gemfile." -- 1.7.1 From d599e94e45d5937ca80d9416a571c0e628b95bd3 Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 02:16:48 -0700 Subject: [PATCH 025/805] require_dependency should require using the normal mechanism if possible to avoid double-requires --- activesupport/lib/active_support/dependencies.rb | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 2b80bd2..1b93eac 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -276,14 +276,22 @@ module ActiveSupport #:nodoc: end def depend_on(file_name, swallow_load_errors = false, message = "No such file to load -- %s.rb") - path = search_for_file(file_name) - require_or_load(path || file_name) - rescue LoadError => load_error - unless swallow_load_errors - if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] - raise LoadError.new(message % file_name).copy_blame!(load_error) + #path = search_for_file(file_name) + require_or_load(file_name) + rescue LoadError + begin + if path = search_for_file(file_name) + require_or_load(path) + else + raise + end + rescue LoadError => load_error + unless swallow_load_errors + if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] + raise LoadError.new(message % file_name).copy_blame!(load_error) + end + raise end - raise end end -- 1.7.1 From bd1cf94a29131c405650d688d672147ecc9c7670 Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 03:20:01 -0700 Subject: [PATCH 026/805] Add a fake UrlRewriter, since instantiating it in tests happens, but is basically crazysauce --- actionpack/lib/action_controller.rb | 1 + .../lib/action_controller/deprecated/url_writer.rb | 5 +++++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index b7250d1..3841f63 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -36,6 +36,7 @@ module ActionController autoload :Dispatcher, 'action_controller/deprecated/dispatcher' autoload :UrlWriter, 'action_controller/deprecated/url_writer' + autoload :UrlReriter, 'action_controller/deprecated/url_writer' autoload :Integration, 'action_controller/deprecated/integration_test' autoload :IntegrationTest, 'action_controller/deprecated/integration_test' autoload :PerformanceTest, 'action_controller/deprecated/performance_test' diff --git a/actionpack/lib/action_controller/deprecated/url_writer.rb b/actionpack/lib/action_controller/deprecated/url_writer.rb index d901cb4..5df868f 100644 --- a/actionpack/lib/action_controller/deprecated/url_writer.rb +++ b/actionpack/lib/action_controller/deprecated/url_writer.rb @@ -6,4 +6,9 @@ module ActionController klass.class_eval { include Rails.application.routes.url_helpers } end end + + class UrlRewriter + def initialize(*) + end + end end -- 1.7.1 From 32d840d98a34d0b8ad13f2d727b4756f9c94d4ca Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 03:20:44 -0700 Subject: [PATCH 027/805] Concernify SanitizeHelper and TextHelper so including TextHelper correctly include SanitizeHelper and extends its ClassMethods --- .../lib/action_view/helpers/sanitize_helper.rb | 1 + actionpack/lib/action_view/helpers/text_helper.rb | 3 +++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index 63f6154..d5638a6 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -7,6 +7,7 @@ module ActionView # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. # These helper methods extend Action View making them callable within your template files. module SanitizeHelper + extend ActiveSupport::Concern # This +sanitize+ helper will html encode all tags and strip all attributes that # aren't specifically allowed. # diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 52a016c..c1de5c8 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -10,6 +10,9 @@ module ActionView # your views. These helper methods extend Action View making them callable # within your template files. module TextHelper + extend ActiveSupport::Concern + + include SanitizeHelper # The preferred method of outputting text in your views is to use the # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods # do not operate as expected in an eRuby code block. If you absolutely must -- 1.7.1 From fbc40a4d9458dd51dc3c9c1c3a53e76f4f448cec Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 03:20:56 -0700 Subject: [PATCH 028/805] Fix a subtle bug involving RAILS_ROOT --- railties/lib/rails/deprecation.rb | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb index 1765c80..55fbc8d 100644 --- a/railties/lib/rails/deprecation.rb +++ b/railties/lib/rails/deprecation.rb @@ -25,11 +25,17 @@ module Rails def method_missing(meth, *args, &block) ActiveSupport::Deprecation.warn("#{@old} is deprecated. Please use #{@new}") unless @warned @warned = true - @target.call.send(meth, *args, &block) + + target = @target.call + if target.respond_to?(meth) + target.send(meth, *args, &block) + else + super + end end end - DeprecatedConstant.deprecate("RAILS_ROOT", "Rails.root") + DeprecatedConstant.deprecate("RAILS_ROOT", "Rails.root.to_s") DeprecatedConstant.deprecate("RAILS_ENV", "Rails.env") DeprecatedConstant.deprecate("RAILS_DEFAULT_LOGGER", "Rails.logger") end -- 1.7.1 From 963638aac8f0d66b82e13d6cddf098afb9bc19dc Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 03:21:37 -0700 Subject: [PATCH 029/805] If a file is in the load path, require it without its full path (in more places) --- activesupport/lib/active_support/dependencies.rb | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 1b93eac..198c124 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -388,8 +388,13 @@ module ActiveSupport #:nodoc: end # Search for a file in autoload_paths matching the provided suffix. - def search_for_file(path_suffix) - path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb") + def search_for_file(file) + path_suffix = file.sub(/(\.rb)?$/, ".rb") + + $:.each do |root| + path = File.join(root, path_suffix) + return file if File.file?(path) + end autoload_paths.each do |root| path = File.join(root, path_suffix) -- 1.7.1 From 2498cdaf14dede0238fa36a84be105c51b5ddd58 Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 4 Aug 2010 04:05:28 -0700 Subject: [PATCH 030/805] I'm unsure how cloning was working in Rails 3 before --- activerecord/lib/active_record/base.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 12736d3..7710aa7 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1400,7 +1400,7 @@ MSG # as it copies the object's attributes only, not its associations. The extent of a "deep" clone is # application specific and is therefore left to the application to implement according to its need. def initialize_copy(other) - callback(:after_initialize) if respond_to_without_attributes?(:after_initialize) + _run_after_initialize_callbacks if respond_to?(:_run_after_initialize_callbacks) cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast) cloned_attributes.delete(self.class.primary_key) -- 1.7.1 From 19c77a0d2b3468c168005c7d79f9b239c4a44fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 4 Aug 2010 14:13:50 +0200 Subject: [PATCH 031/805] Revert "Put lib back on the autoload path" This was causing engines/gems to eager load everything in lib. Another fix is comming soon. This reverts commit 02a5842cd09bd75de4c2fdb6b474c6c0ff163ebf. --- railties/lib/rails/engine/configuration.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 2d784c6..f7a523c 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -20,7 +20,7 @@ module Rails paths.app.models "app/models", :eager_load => true paths.app.mailers "app/mailers", :eager_load => true paths.app.views "app/views" - paths.lib "lib", :eager_load => true + paths.lib "lib", :load_path => true paths.lib.tasks "lib/tasks", :glob => "**/*.rake" paths.config "config" paths.config.initializers "config/initializers", :glob => "**/*.rb" -- 1.7.1 From f316a851ddf3290ea4fda0fe4b1539bc9809b6ac Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 4 Aug 2010 08:44:35 -0700 Subject: [PATCH 032/805] do not pass AR objects to ARel --- .../lib/active_record/relation/finder_methods.rb | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index bad9af2..b34c119 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -286,6 +286,8 @@ module ActiveRecord end def find_one(id) + id = id.id if ActiveRecord::Base === id + record = where(primary_key.eq(id)).first unless record -- 1.7.1 From 87365272e941134652fdaa1727b63866c0ccb118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 4 Aug 2010 14:18:24 -0300 Subject: [PATCH 033/805] Revert "If a file is in the load path, require it without its full path (in more places)" Caused failures in ActionMailer test suite. This reverts commit 963638aac8f0d66b82e13d6cddf098afb9bc19dc. --- activesupport/lib/active_support/dependencies.rb | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 198c124..1b93eac 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -388,13 +388,8 @@ module ActiveSupport #:nodoc: end # Search for a file in autoload_paths matching the provided suffix. - def search_for_file(file) - path_suffix = file.sub(/(\.rb)?$/, ".rb") - - $:.each do |root| - path = File.join(root, path_suffix) - return file if File.file?(path) - end + def search_for_file(path_suffix) + path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb") autoload_paths.each do |root| path = File.join(root, path_suffix) -- 1.7.1 From 4da32babdf04a151ec633cebf412fa6ca61e556d Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Wed, 4 Aug 2010 18:58:18 +0200 Subject: [PATCH 034/805] Reload action_methods in AbstractController after defining new method. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionmailer/test/base_test.rb | 12 ++++++++++++ actionpack/lib/abstract_controller/base.rb | 12 ++++++++++++ .../test/abstract/abstract_controller_test.rb | 14 ++++++++++++++ activesupport/lib/active_support/callbacks.rb | 5 ++++- 4 files changed, 42 insertions(+), 1 deletions(-) diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index e2b9df5..fec0ecf 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -507,6 +507,18 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Thanks for signing up this afternoon", mail.subject) end + test "action methods should be refreshed after defining new method" do + class FooMailer < ActionMailer::Base + # this triggers action_methods + self.respond_to?(:foo) + + def notify + end + end + + assert_equal ["notify"], FooMailer.action_methods + end + protected # Execute the block setting the given values and restoring old values after diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 8a83378..db0a673 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -72,6 +72,13 @@ module AbstractController end end + # action_methods are cached and there is sometimes need to refresh + # them. clear_action_methods! allows you to do that, so next time + # you run action_methods, they will be recalculated + def clear_action_methods! + @action_methods = nil + end + # Returns the full controller name, underscored, without the ending Controller. # For instance, MyApp::MyPostsController would return "my_app/my_posts" for # controller_name. @@ -81,6 +88,11 @@ module AbstractController def controller_path @controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous? end + + def method_added(name) + super + clear_action_methods! + end end abstract! diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb index 3b5013a..1985549 100644 --- a/actionpack/test/abstract/abstract_controller_test.rb +++ b/actionpack/test/abstract/abstract_controller_test.rb @@ -250,5 +250,19 @@ module AbstractController end end + class Me6 < AbstractController::Base + self.action_methods + + def index + end + end + + class TestActionMethodsReloading < ActiveSupport::TestCase + + test "action_methods should be reloaded after defining a new method" do + assert_equal ["index"], Me6.action_methods + end + end + end end diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 1c7802f..0fafd56 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -419,7 +419,10 @@ module ActiveSupport @_keyed_callbacks ||= {} @_keyed_callbacks[name] ||= begin str = send("_#{kind}_callbacks").compile(name, object) - class_eval "def #{name}() #{str} end", __FILE__, __LINE__ + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{name}() #{str} end + protected :#{name} + RUBY_EVAL true end end -- 1.7.1 From 906ef233e4b41d5b9deae46b9c80cea47936bb0d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 4 Aug 2010 14:11:09 -0700 Subject: [PATCH 035/805] fisting indentation --- activerecord/lib/active_record/relation/batches.rb | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 412be89..ecdf7c5 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -50,9 +50,9 @@ module ActiveRecord def find_in_batches(options = {}) relation = self - if orders.present? || taken.present? - ActiveRecord::Base.logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size") - end + if orders.present? || taken.present? + 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? -- 1.7.1 From ba9602b9e7fc02118e5bda3c1330dbd2f6274a09 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 4 Aug 2010 14:22:20 -0700 Subject: [PATCH 036/805] call to_a since we are not passing anything to all() --- activerecord/lib/active_record/relation/batches.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index ecdf7c5..d7494eb 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -73,7 +73,7 @@ module ActiveRecord break if records.size < batch_size if primary_key_offset = records.last.id - records = relation.where(primary_key.gt(primary_key_offset)).all + records = relation.where(primary_key.gt(primary_key_offset)).to_a else raise "Primary key not included in the custom select clause" end -- 1.7.1 From 18bcc548bfcccfdc037987f2086be2cab743bdb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Wed, 4 Aug 2010 19:41:05 +0800 Subject: [PATCH 037/805] Typo in class name --- actionpack/lib/action_controller.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 3841f63..63d8372 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -36,7 +36,7 @@ module ActionController autoload :Dispatcher, 'action_controller/deprecated/dispatcher' autoload :UrlWriter, 'action_controller/deprecated/url_writer' - autoload :UrlReriter, 'action_controller/deprecated/url_writer' + autoload :UrlRewriter, 'action_controller/deprecated/url_writer' autoload :Integration, 'action_controller/deprecated/integration_test' autoload :IntegrationTest, 'action_controller/deprecated/integration_test' autoload :PerformanceTest, 'action_controller/deprecated/performance_test' -- 1.7.1 From 84d5461d43678b11ad15dcb354598a2fa94377b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Thu, 5 Aug 2010 05:18:29 +0800 Subject: [PATCH 038/805] Fixed broken test suite - there was problem with namespacing in DeprecatedConstant class --- railties/lib/rails/deprecation.rb | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb index 55fbc8d..b9aedd3 100644 --- a/railties/lib/rails/deprecation.rb +++ b/railties/lib/rails/deprecation.rb @@ -18,12 +18,12 @@ module Rails def initialize(old, new) @old, @new = old, new - @target = eval "proc { #{new} }" + @target = ::Kernel.eval "proc { #{@new} }" @warned = false end def method_missing(meth, *args, &block) - ActiveSupport::Deprecation.warn("#{@old} is deprecated. Please use #{@new}") unless @warned + ::ActiveSupport::Deprecation.warn("#{@old} is deprecated. Please use #{@new}") unless @warned @warned = true target = @target.call -- 1.7.1 From 05a49c77181db8f8d0700ac57fc7f13d1fd112a5 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 4 Aug 2010 16:22:16 -0700 Subject: [PATCH 039/805] avoid passing lists of lists to the group clause --- .../lib/active_record/relation/query_methods.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index a92d180..dfacde8 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -31,7 +31,7 @@ module ActiveRecord end def group(*args) - clone.tap {|r| r.group_values += args if args.present? } + clone.tap {|r| r.group_values += args.flatten if args.present? } end def order(*args) -- 1.7.1 From 2005f8234a8001585b484e43727f20317ca958c6 Mon Sep 17 00:00:00 2001 From: Tom Stuart Date: Thu, 5 Aug 2010 09:02:30 +0100 Subject: [PATCH 040/805] Fix ActiveSupport::Callbacks' define_callbacks and ActiveSupport::Concern documentation to look like native English --- activesupport/lib/active_support/callbacks.rb | 6 +++--- activesupport/lib/active_support/concern.rb | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 50a4ce6..85cd4db 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -571,9 +571,9 @@ module ActiveSupport # # would trigger Audit#before_save instead. That's constructed by calling # "#{kind}_#{name}" on the given instance. In this case "kind" is "before" and - # "name" is "save". In this context treat ":kind" and ":name" as special thing where - # ":kind" refers to "callback type(before/after)" and ":name" refers to the method on - # which callbacks are being defined. + # "name" is "save". In this context ":kind" and ":name" have special meanings: ":kind" + # refers to the kind of callback (before/after/around) and ":name" refers to the + # method on which callbacks are being defined. # # A declaration like # diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb index 408d327..2d87e8d 100644 --- a/activesupport/lib/active_support/concern.rb +++ b/activesupport/lib/active_support/concern.rb @@ -4,33 +4,33 @@ # def self.included(base) # base.send(:extend, ClassMethods) # base.send(:include, InstanceMethods) -# scope :foo, :conditions => {:created_at => nil} +# scope :foo, :conditions => { :created_at => nil } # end # # module ClassMethods -# def cm; puts 'I am class method'; end +# def cm; puts 'I am a class method'; end # end # # module InstanceMethods -# def im; puts 'I am instance method'; end +# def im; puts 'I am an instance method'; end # end # end # -# By using ActiveSupport::Concern above module could be written as: +# By using ActiveSupport::Concern the above module could instead be written as: # # module M # extend ActiveSupport::Concern # -# included do -# scope :foo, :conditions => {:created_at => nil} +# included do +# scope :foo, :conditions => { :created_at => nil } # end # # module ClassMethods -# def cm; puts 'I am class method'; end +# def cm; puts 'I am a class method'; end # end # # module InstanceMethods -# def im; puts 'I am instance method'; end +# def im; puts 'I am an instance method'; end # end # end module ActiveSupport -- 1.7.1 From e34fb808dbf469e7aa19b8e63948ed9750bdc3b2 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 5 Aug 2010 13:51:45 +0200 Subject: [PATCH 041/805] AS guide: documents DateTime#advance --- .../source/active_support_core_extensions.textile | 37 ++++++++++++++++++-- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 136fcde..d7d1423 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -2979,11 +2979,11 @@ Note in the previous example that increments may be negative. To perform the computation the method first increments years, then months, then weeks, and finally days. This order is important towards the end of months. Say for example we are at the end of February of 2010, and we want to move one month and one day forward. -The method +advance+ advances first one month, and the one day, the result is: +The method +advance+ advances first one month, and then one day, the result is: -Date.new(2010, 2, 28).advance(:months => 1, :day => 1) -# => Sun, 28 Mar 2010 +Date.new(2010, 2, 28).advance(:months => 1, :days => 1) +# => Sun, 29 Mar 2010 While if it did it the other way around the result would be different: @@ -3132,6 +3132,37 @@ now.utc? # => false now.utc.utc? # => true +h6(#datetime-advance). +advance+ + +The most generic way to jump to another datetime is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, +:hours+, +:minutes+, and +:seconds+, and returns a datetime advanced as much as the present keys indicate. + + +d = DateTime.current +# => Thu, 05 Aug 2010 11:33:31 +0000 +d.advance(:years => 1, :months => 1, :days => 1, :hours => 1, :minutes => 1, :seconds => 1) +# => Tue, 06 Sep 2011 12:34:32 +0000 + + +This method first computes the destination date passing +:years+, +:months+, +:weeks+, and +:days+ to +Date#advance+ documented above. After that, it adjusts the time calling +since+ with the number of seconds to advance. This order is relevant, a different ordering would give different datetimes in some edge-cases. The example in +Date#advance+ applies, and we can extend it to show order relevance related to the time bits. + +If we first move the date bits (that have also a relative order of processing, as documented before), and then the time bits we get for example the following computation: + + +d = DateTime.new(2010, 2, 28, 23, 59, 59) +# => Sun, 28 Feb 2010 23:59:59 +0000 +d.advance(:months => 1, :seconds => 1) +# => Mon, 29 Mar 2010 00:00:00 +0000 + + +but if we computed them the other way around, the result would be different: + + +d.advance(:seconds => 1).advance(:months => 1) +# => Thu, 01 Apr 2010 00:00:00 +0000 + + +WARNING: Since +DateTime+ is not DST-aware you can end up in a non-existing point in time with no warning or error telling you so. + h5(#datetime-changing-components). Changing Components The method +change+ allows you to get a new datetime which is the same as the receiver except for the given options, which may include +:year+, +:month+, +:day+, +:hour+, +:min+, +:sec+, +:offset+, +:start+: -- 1.7.1 From 0a86cb597257d7cee356777bb8967823796e79aa Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 5 Aug 2010 08:15:07 -0700 Subject: [PATCH 042/805] fixing whitespace errors --- activerecord/lib/active_record/schema.rb | 2 +- activerecord/lib/active_record/schema_dumper.rb | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb index e278308..c1bc321 100644 --- a/activerecord/lib/active_record/schema.rb +++ b/activerecord/lib/active_record/schema.rb @@ -2,7 +2,7 @@ require 'active_support/core_ext/object/blank' module ActiveRecord # = Active Record Schema - # + # # Allows programmers to programmatically define a schema in a portable # DSL. This means you can define tables, indexes, etc. without using SQL # directly, so your applications can more easily support multiple diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index a475777..e9af20e 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -8,13 +8,13 @@ module ActiveRecord # output format (i.e., ActiveRecord::Schema). class SchemaDumper #:nodoc: private_class_method :new - + ## # :singleton-method: - # A list of tables which should not be dumped to the schema. + # A list of tables which should not be dumped to the schema. # Acceptable values are strings as well as regexp. # This setting is only used if ActiveRecord::Base.schema_format == :ruby - cattr_accessor :ignore_tables + cattr_accessor :ignore_tables @@ignore_tables = [] def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT) @@ -71,7 +71,7 @@ HEADER else raise StandardError, 'ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values.' end - end + end table(tbl, stream) end end @@ -87,7 +87,7 @@ HEADER elsif @connection.respond_to?(:primary_key) pk = @connection.primary_key(table) end - + tbl.print " create_table #{table.inspect}" if columns.detect { |c| c.name == pk } if pk != 'id' @@ -105,7 +105,7 @@ HEADER next if column.name == pk spec = {} spec[:name] = column.name.inspect - + # AR has an optimisation which handles zero-scale decimals as integers. This # code ensures that the dumper still dumps the column as a decimal. spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) } @@ -148,7 +148,7 @@ HEADER tbl.puts " end" tbl.puts - + indexes(table, tbl) tbl.rewind @@ -158,7 +158,7 @@ HEADER stream.puts "# #{e.message}" stream.puts end - + stream end @@ -172,7 +172,7 @@ HEADER value.inspect end end - + def indexes(table, stream) if (indexes = @connection.indexes(table)).any? add_index_statements = indexes.map do |index| -- 1.7.1 From 06e4c48815d810fef516241e1978ea0818501e03 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Thu, 5 Aug 2010 11:55:20 -0400 Subject: [PATCH 043/805] more documentation for class_inheritable_* --- .../core_ext/class/inheritable_attributes.rb | 22 ++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb index 92d6dba..a33c772 100644 --- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -5,6 +5,10 @@ require 'active_support/core_ext/array/extract_options' module ClassInheritableAttributes # :nodoc: end +# It is recommend to use class_attribute over methods defined in this file. Please +# refer to documentation for class_attribute for more infor. Officially it is not +# deprected but class_attribute is faster. +# # Allows attributes to be shared within an inheritance hierarchy. Each descendant gets a copy of # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements # to, for example, an array without those additions being shared with either their parent, siblings, or @@ -12,6 +16,24 @@ end # # The copies of inheritable parent attributes are added to subclasses when they are created, via the # +inherited+ hook. +# +# class Person +# class_inheritable_accessor :hair_colors +# end +# +# Person.hair_colors = [:brown, :black, :blonde, :red] +# Person.hair_colors #=> [:brown, :black, :blonde, :red] +# Person.new.hair_colors #=> [:brown, :black, :blonde, :red] +# +# To opt out of the instance writer method, pass :instance_writer => false. +# To opt out of the instance reader method, pass :instance_reader => false. +# +# class Person +# cattr_accessor :hair_colors :instance_writer => false, :instance_reader => false +# end +# +# Person.new.hair_colors = [:brown] # => NoMethodError +# Person.new.hair_colors # => NoMethodError class Class # :nodoc: def class_inheritable_reader(*syms) options = syms.extract_options! -- 1.7.1 From 148dd2eac67e7b1e2e92973e952ed6ee06dcd98b Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Thu, 5 Aug 2010 16:35:40 -0400 Subject: [PATCH 044/805] fixing typo --- .../core_ext/class/inheritable_attributes.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb index a33c772..d7a30cf 100644 --- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -6,7 +6,7 @@ module ClassInheritableAttributes # :nodoc: end # It is recommend to use class_attribute over methods defined in this file. Please -# refer to documentation for class_attribute for more infor. Officially it is not +# refer to documentation for class_attribute for more information. Officially it is not # deprected but class_attribute is faster. # # Allows attributes to be shared within an inheritance hierarchy. Each descendant gets a copy of -- 1.7.1 From bed98b9bf2023f75641fa79ffe7d95d70cf8b726 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 6 Aug 2010 13:33:02 +0200 Subject: [PATCH 045/805] AR guide: fixes a query --- .../guides/source/active_record_querying.textile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index 5c4ed3a..53095a2 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -764,7 +764,7 @@ This loads all the posts and the associated category and comments for each post. h5. Nested Associations Hash -Category.find(1).includes(:posts => [{:comments => :guest}, :tags]) +Category.includes(:posts => [{:comments => :guest}, :tags]).find(1) This will find the category with id 1 and eager load all of the associated posts, the associated posts' tags and comments, and every comment's guest association. -- 1.7.1 From 0bb8d0561a30abbadad43a18896f684a178fe261 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 6 Aug 2010 17:29:52 +0200 Subject: [PATCH 046/805] AS guide: documents calculations with Time objects --- .../source/active_support_core_extensions.textile | 112 +++++++++++++++++--- 1 files changed, 99 insertions(+), 13 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index d7d1423..9d9053d 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3053,30 +3053,30 @@ h4(#date-conversions). Conversions h3. Extensions to +DateTime+ -NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+. - WARNING: +DateTime+ is not aware of DST rules and so some of these methods have edge cases when a DST change is going on. For example +seconds_since_midnight+ might not return the real amount in such a day. h4(#calculations-datetime). Calculations +NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+. + The class +DateTime+ is a subclass of +Date+ so by loading +active_support/core_ext/date/calculations.rb+ you inherit these methods and their aliases, except that they will always return datetimes: yesterday tomorrow -beginning_of_week -end_on_week +beginning_of_week (monday, at_beginning_of_week) +end_on_week (at_end_of_week) next_week months_ago months_since -beginning_of_month -end_of_month +beginning_of_month (at_beginning_of_month) +end_of_month (at_end_of_month) prev_month next_month -beginning_of_quarter -end_of_quarter -beginning_of_year -end_of_year +beginning_of_quarter (at_beginning_of_quarter) +end_of_quarter (at_end_of_quarter) +beginning_of_year (at_beginning_of_year) +end_of_year (at_end_of_year) years_ago years_since prev_year @@ -3086,10 +3086,10 @@ next_year The following methods are reimplemented so you do *not* need to load +active_support/core_ext/date/calculations.rb+ for these ones: -beginning_of_day +beginning_of_day (midnight, at_midnight, at_beginning_of_day) end_of_day ago -since +since (in) On the other hand, +advance+ and +change+ are also defined and support more options, they are documented below. @@ -3199,7 +3199,93 @@ h4(#datetime-conversions). Conversions h3. Extensions to +Time+ -... +h4(#time-calculations). Calculations + +NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+. + +Active Support adds to +Time+ many of the methods available for +DateTime+: + + +past? +today? +future? +yesterday +tomorrow +seconds_since_midnight +change +advance +ago +since (in) +beginning_of_day (midnight, at_midnight, at_beginning_of_day) +end_of_day +beginning_of_week (monday, at_beginning_of_week) +end_on_week (at_end_of_week) +next_week +months_ago +months_since +beginning_of_month (at_beginning_of_month) +end_of_month (at_end_of_month) +prev_month +next_month +beginning_of_quarter (at_beginning_of_quarter) +end_of_quarter (at_end_of_quarter) +beginning_of_year (at_beginning_of_year) +end_of_year (at_end_of_year) +years_ago +years_since +prev_year +next_year + + +They are analogous. Please refer to their documentation above and take into account the following differences: + +* +change+ accepts an additional +:usec+ option. +* +Time+ understands DST, so you get correct DST calculations as in + + +# In Barcelona, 2010/03/28 02:00 +0100 becomes 2010/03/28 03:00 +0200 due to DST. +t = Time.local_time(2010, 3, 28, 1, 59, 59) +# => Sun Mar 28 01:59:59 +0100 2010 +t.advance(:seconds => 1) +# => Sun Mar 28 03:00:00 +0200 2010 + + +* If +since+ or +ago+ jump to a time that can't be expressed with +Time+ a +DateTime+ object is returned instead. + +h4. Time Constructors + +Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+: + + +Time.zone_default +# => # +Time.current +# => Fri, 06 Aug 2010 17:11:58 CEST +02:00 + + +Analogously to +DateTime+, the predicates +past?+, and +future?+ are relative to +Time.current+. + +Use the +local_time+ class method to create time objects honoring the user time zone: + + +Time.zone_default +# => # +Time.local_time(2010, 8, 15) +# => Sun Aug 15 00:00:00 +0200 2010 + + +The +utc_time+ class method returns a time in UTC: + + +Time.zone_default +# => # +Time.utc_time(2010, 8, 15) +# => Sun Aug 15 00:00:00 UTC 2010 + + +Both +local_time+ and +utc_time+ accept up to seven positional arguments: year, month, day, hour, min, sec, usec. Year is mandatory, month and day default to 1, and the rest default to 0. + +If the time to be constructed lies beyond the range supported by +Time+ in the runtime platform, usecs are discarded and a +DateTime+ object is returned instead. h3. Extensions to +Process+ -- 1.7.1 From 8fb0c9f509080ec1ac11c298309be157174d8712 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 6 Aug 2010 11:31:05 -0700 Subject: [PATCH 047/805] do not rely on arel class structure --- activerecord/lib/active_record/relation.rb | 4 +++- activerecord/test/cases/method_scoping_test.rb | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index deacced..30be723 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -319,7 +319,9 @@ module ActiveRecord def scope_for_create @scope_for_create ||= begin @create_with_value || Hash[ - @where_values.grep(Arel::Predicates::Equality).map { |where| + @where_values.find_all { |w| + w.respond_to?(:operator) && w.operator == :== + }.map { |where| [where.operand1.name, where.operand2.respond_to?(:value) ? where.operand2.value : where.operand2] diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb index 774b50e..5256ab8 100644 --- a/activerecord/test/cases/method_scoping_test.rb +++ b/activerecord/test/cases/method_scoping_test.rb @@ -208,6 +208,13 @@ class MethodScopingTest < ActiveRecord::TestCase end end + def test_scope_for_create_only_uses_equal + table = VerySpecialComment.arel_table + relation = VerySpecialComment.scoped + relation.where_values << table[:id].not_eq(1) + assert_equal({:type => "VerySpecialComment"}, relation.send(:scope_for_create)) + end + def test_scoped_create new_comment = nil -- 1.7.1 From a897a1f4a38ad4d8766bf1d063d71ffcd733a935 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 6 Aug 2010 14:52:33 -0700 Subject: [PATCH 048/805] sorry AR, my privates are none of your business --- activerecord/test/cases/relations_test.rb | 7 ------- 1 files changed, 0 insertions(+), 7 deletions(-) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index c9313fe..02c8c60 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -192,13 +192,6 @@ class RelationTest < ActiveRecord::TestCase end end - def test_respond_to_private_arel_methods - relation = Topic.scoped - - assert ! relation.respond_to?(:matching_attributes) - assert relation.respond_to?(:matching_attributes, true) - end - def test_respond_to_dynamic_finders relation = Topic.scoped -- 1.7.1 From 001a5747858f2636cce48891ebc5af132c843b05 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 6 Aug 2010 15:23:11 -0700 Subject: [PATCH 049/805] test to ensure that respond_to? delegates to arel --- activerecord/test/cases/relations_test.rb | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 02c8c60..ac7b501 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -192,6 +192,25 @@ class RelationTest < ActiveRecord::TestCase end end + def test_respond_to_delegates_to_relation + relation = Topic.scoped + fake_arel = Struct.new(:responds) { + def respond_to? method, access = false + responds << [method, access] + end + }.new [] + + relation.extend(Module.new { attr_accessor :arel }) + relation.arel = fake_arel + + relation.respond_to?(:matching_attributes) + assert_equal [:matching_attributes, false], fake_arel.responds.first + + fake_arel.responds = [] + relation.respond_to?(:matching_attributes, true) + assert_equal [:matching_attributes, true], fake_arel.responds.first + end + def test_respond_to_dynamic_finders relation = Topic.scoped -- 1.7.1 From 91930dc30b62d4e29cad0fa10d0a8f72889b81b2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 6 Aug 2010 16:38:53 -0700 Subject: [PATCH 050/805] reduce the number of times current_connection_id is called in with_connection() --- .../abstract/connection_pool.rb | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) 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 9d0251d..02a8f4e 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -103,8 +103,8 @@ module ActiveRecord # Signal that the thread is finished with the current connection. # #release_connection releases the connection-thread association # and returns the connection to the pool. - def release_connection - conn = @reserved_connections.delete(current_connection_id) + def release_connection(with_id = current_connection_id) + conn = @reserved_connections.delete(with_id) checkin conn if conn end @@ -112,10 +112,11 @@ module ActiveRecord # exists checkout a connection, yield it to the block, and checkin the # connection when finished. def with_connection - fresh_connection = true unless @reserved_connections[current_connection_id] + connection_id = current_connection_id + fresh_connection = true unless @reserved_connections[connection_id] yield connection ensure - release_connection if fresh_connection + release_connection(connection_id) if fresh_connection end # Returns true if a connection has already been opened. -- 1.7.1 From 413c9c82356bd96ac01406970596859ef357577e Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 7 Aug 2010 01:42:09 +0200 Subject: [PATCH 051/805] adds Abstract Controller to the API --- Rakefile | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Rakefile b/Rakefile index 4e56da5..0e6acb5 100644 --- a/Rakefile +++ b/Rakefile @@ -90,6 +90,7 @@ RDoc::Task.new do |rdoc| rdoc.rdoc_files.include('actionpack/README.rdoc') rdoc.rdoc_files.include('actionpack/CHANGELOG') + rdoc.rdoc_files.include('actionpack/lib/abstract_controller/**/*.rb') rdoc.rdoc_files.include('actionpack/lib/action_controller/**/*.rb') rdoc.rdoc_files.include('actionpack/lib/action_dispatch/**/*.rb') rdoc.rdoc_files.include('actionpack/lib/action_view/**/*.rb') -- 1.7.1 From 5aec933385aa6f3485b04eff897aaef32f8b2c73 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 7 Aug 2010 15:18:22 +0200 Subject: [PATCH 052/805] quick hack: hijacks the predicate RDoc::Parser.binary? so that it does not consider a handful of ordinary Ruby files in the Rails tree as binary (and thus excluded from the API) --- Rakefile | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/Rakefile b/Rakefile index 0e6acb5..aab4f5f 100644 --- a/Rakefile +++ b/Rakefile @@ -5,6 +5,31 @@ require 'rake' require 'rdoc/task' require 'rake/gempackagetask' +# RDoc skips some files in the Rails tree due to its binary? predicate. This is a quick +# hack for edge docs, until we decide which is the correct way to address this issue. +# If not fixed in RDoc itself, via an option or something, we should probably move this +# to railties and use it also in doc:rails. +def hijack_rdoc! + require "rdoc/parser" + class << RDoc::Parser + def binary?(file) + s = File.read(file, 1024) or return false + + if s[0, 2] == Marshal.dump('')[0, 2] then + true + elsif file =~ /\.erb\.rb$/ then # ORIGINAL is file =~ /erb\.rb$/ + false + elsif s.index("\x00") then # ORIGINAL is s.scan(/<%|%>/).length >= 4 || s.index("\x00") + true + elsif 0.respond_to? :fdiv then + s.count("^ -~\t\r\n").fdiv(s.size) > 0.3 + else # HACK 1.8.6 + (s.count("^ -~\t\r\n").to_f / s.size) > 0.3 + end + end + end +end + PROJECTS = %w(activesupport activemodel actionpack actionmailer activeresource activerecord railties) desc 'Run all tests by default' @@ -63,6 +88,8 @@ end desc "Generate documentation for the Rails framework" RDoc::Task.new do |rdoc| + hijack_rdoc! + rdoc.rdoc_dir = 'doc/rdoc' rdoc.title = "Ruby on Rails Documentation" -- 1.7.1 From 78c7705b32ed2eed32d8430caede467233c06830 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 7 Aug 2010 20:10:01 +0200 Subject: [PATCH 053/805] undoes one of the modifications to RDoc::Parser.binary? --- Rakefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Rakefile b/Rakefile index aab4f5f..ceb0e83 100644 --- a/Rakefile +++ b/Rakefile @@ -17,7 +17,7 @@ def hijack_rdoc! if s[0, 2] == Marshal.dump('')[0, 2] then true - elsif file =~ /\.erb\.rb$/ then # ORIGINAL is file =~ /erb\.rb$/ + elsif file =~ /erb\.rb$/ then false elsif s.index("\x00") then # ORIGINAL is s.scan(/<%|%>/).length >= 4 || s.index("\x00") true -- 1.7.1 From 783dc5207b08e5ef64f0841acefe32db2a7ffdf4 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 8 Aug 2010 11:28:50 +0200 Subject: [PATCH 054/805] updates horo dependency to 1.0.1 --- Gemfile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Gemfile b/Gemfile index c8dbcc0..71dc1f3 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ gem "rails", :path => File.dirname(__FILE__) gem "rake", ">= 0.8.7" gem "mocha", ">= 0.9.8" gem "rdoc", ">= 2.5.9" -gem "horo" +gem "horo", ">= 1.0.1" # AS gem "memcache-client", ">= 1.8.5" -- 1.7.1 From 4b18d3c21019cd90aa6f07c9b6a21362aa047390 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 8 Aug 2010 18:29:58 +0200 Subject: [PATCH 055/805] routing guide: documents the CONTROLLER environment variable understood by the routes task --- railties/guides/source/routing.textile | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index 7b665d8..625941b 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -762,6 +762,12 @@ formatted_users GET /users.:format {:controller=>"users", :action=>"index"} POST /users.:format {:controller=>"users", :action=>"create"} +You may restrict the listing to the routes that map to a particular controller setting the +CONTROLLER+ environment variable: + + +$ CONTROLLER=users rake routes + + TIP: You'll find that the output from +rake routes+ is much more readable if you widen your terminal window until the output lines don't wrap. h4. Testing Routes -- 1.7.1 From d55491c8449db994c421626166a7a174e0e83f64 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Fri, 6 Aug 2010 15:51:52 -0400 Subject: [PATCH 056/805] correcting wrong example --- .../core_ext/class/inheritable_attributes.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb index d7a30cf..e844cf5 100644 --- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -29,7 +29,7 @@ end # To opt out of the instance reader method, pass :instance_reader => false. # # class Person -# cattr_accessor :hair_colors :instance_writer => false, :instance_reader => false +# class_inheritable_accessor :hair_colors :instance_writer => false, :instance_reader => false # end # # Person.new.hair_colors = [:brown] # => NoMethodError -- 1.7.1 From f7996be0c762eb81b36264383179b3bdf739e2db Mon Sep 17 00:00:00 2001 From: Daniel McNevin Date: Sun, 8 Aug 2010 19:57:42 -0400 Subject: [PATCH 057/805] updated the action_controller guide with the new session configuration options --- .../source/action_controller_overview.textile | 41 +++++++++++++------ 1 files changed, 28 insertions(+), 13 deletions(-) diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index 038ca90..ff11260 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -159,23 +159,38 @@ Read more about session storage in the "Security Guide":security.html. If you need a different session storage mechanism, you can change it in the +config/initializers/session_store.rb+ file: -# Use the database for sessions instead of the cookie-based default, -# which shouldn't be used to store highly confidential information -# (create the session table with "rake db:sessions:create") -# ActionController::Base.session_store = :active_record_store + # Use the database for sessions instead of the cookie-based default, + # which shouldn't be used to store highly confidential information + # (create the session table with "rake db:sessions:create") + # YourApp::Application.config.session_store :active_record_store -Rails sets up a session key (the name of the cookie) and (for the CookieStore) a secret key used when signing the session data. These can also be changed in +config/initializers/session_store.rb+: +Rails sets up a session key (the name of the cookie) when signing the session data. These can also be changed in +config/initializers/session_store.rb+: -# Your secret key for verifying cookie session data integrity. -# If you change this key, all old sessions will become invalid! -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -ActionController::Base.session = { - :key => '_yourappname_session', - :secret => '4f50711b8f0f49572...' -} + # Be sure to restart your server when you modify this file. + + YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session' + + +You can also pass a +:domain+ key and specify the domain name for the cookie: + + + # Be sure to restart your server when you modify this file. + + YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session', :domain => ".test.com" + + +Rails sets up (for the CookieStore) a secret key used for signing the session data. This can be changed in +config/initializers/secret_token.rb+ + + + # Be sure to restart your server when you modify this file. + + # Your secret key for verifying the integrity of signed cookies. + # If you change this key, all old signed cookies will become invalid! + # Make sure the secret is at least 30 characters and all random, + # no regular words or you'll be exposed to dictionary attacks. + YourApp::Application.config.secret_token = '49d3f3de9ed86c74b94ad6bd0...' NOTE: Changing the secret when using the CookieStore will invalidate all existing sessions. -- 1.7.1 From 5c109e243f13a632637236786535a3a0f344115a Mon Sep 17 00:00:00 2001 From: Adam Meehan Date: Mon, 9 Aug 2010 13:44:04 +1000 Subject: [PATCH 058/805] typo in AM --- activemodel/lib/active_model/attribute_methods.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 817640b..a43436e 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -283,7 +283,7 @@ module ActiveModel @attribute_methods_generated = true end - # Removes all the preiously dynamically defined methods from the class + # Removes all the previously dynamically defined methods from the class def undefine_attribute_methods generated_attribute_methods.module_eval do instance_methods.each { |m| undef_method(m) } -- 1.7.1 From 4d4b865b1173d80b935876d09f67a35feb0effc9 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 9 Aug 2010 12:21:21 +0200 Subject: [PATCH 059/805] AC guide: commit review, block examples go at column 0, use .example.com as example domain --- .../source/action_controller_overview.textile | 30 ++++++++++---------- 1 files changed, 15 insertions(+), 15 deletions(-) diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index ff11260..ec2d5b2 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -159,41 +159,41 @@ Read more about session storage in the "Security Guide":security.html. If you need a different session storage mechanism, you can change it in the +config/initializers/session_store.rb+ file: - # Use the database for sessions instead of the cookie-based default, - # which shouldn't be used to store highly confidential information - # (create the session table with "rake db:sessions:create") - # YourApp::Application.config.session_store :active_record_store +# Use the database for sessions instead of the cookie-based default, +# which shouldn't be used to store highly confidential information +# (create the session table with "rake db:sessions:create") +# YourApp::Application.config.session_store :active_record_store Rails sets up a session key (the name of the cookie) when signing the session data. These can also be changed in +config/initializers/session_store.rb+: - # Be sure to restart your server when you modify this file. +# Be sure to restart your server when you modify this file. - YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session' +YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session' You can also pass a +:domain+ key and specify the domain name for the cookie: - # Be sure to restart your server when you modify this file. +# Be sure to restart your server when you modify this file. - YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session', :domain => ".test.com" +YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session', :domain => ".example.com" Rails sets up (for the CookieStore) a secret key used for signing the session data. This can be changed in +config/initializers/secret_token.rb+ - # Be sure to restart your server when you modify this file. +# Be sure to restart your server when you modify this file. - # Your secret key for verifying the integrity of signed cookies. - # If you change this key, all old signed cookies will become invalid! - # Make sure the secret is at least 30 characters and all random, - # no regular words or you'll be exposed to dictionary attacks. - YourApp::Application.config.secret_token = '49d3f3de9ed86c74b94ad6bd0...' +# Your secret key for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +YourApp::Application.config.secret_token = '49d3f3de9ed86c74b94ad6bd0...' -NOTE: Changing the secret when using the CookieStore will invalidate all existing sessions. +NOTE: Changing the secret when using the +CookieStore+ will invalidate all existing sessions. h4. Accessing the Session -- 1.7.1 From 28d82bd2e9bb3eae13b58949d264bd631d3820f6 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 9 Aug 2010 13:31:42 +0200 Subject: [PATCH 060/805] adds URL to the body generated by the redirect macro in the routes mapper as per the RFC, extracts common test pattern into a test macro, adds a test to cover the :status option --- actionpack/lib/action_dispatch/routing/mapper.rb | 5 ++- actionpack/test/dispatch/routing_test.rb | 55 ++++++++++------------ 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 526c97f..c118c72 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,3 +1,4 @@ +require 'erb' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/object/blank' @@ -277,7 +278,6 @@ module ActionDispatch path = args.shift || block path_proc = path.is_a?(Proc) ? path : proc { |params| path % params } status = options[:status] || 301 - body = 'Moved Permanently' lambda do |env| req = Request.new(env) @@ -290,11 +290,14 @@ module ActionDispatch uri.host ||= req.host uri.port ||= req.port unless req.port == 80 + body = %(You are being redirected.) + headers = { 'Location' => uri.to_s, 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s } + [ status, headers, [body] ] end end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 4808663..3f090b7 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -1,3 +1,4 @@ +require 'erb' require 'abstract_unit' require 'controller/fake_controllers' @@ -56,7 +57,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest match 'account/proc/:name', :to => redirect {|params| "/#{params[:name].pluralize}" } match 'account/proc_req' => redirect {|params, req| "/#{req.method}" } - match 'account/google' => redirect('http://www.google.com/') + match 'account/google' => redirect('http://www.google.com/', :status => 302) match 'openid/login', :via => [:get, :post], :to => "openid#login" @@ -501,9 +502,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_login_redirect with_test_routes do get '/account/login' - assert_equal 301, @response.status - assert_equal 'http://www.example.com/login', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com/login' end end @@ -511,18 +510,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest with_test_routes do assert_equal '/account/logout', logout_redirect_path get '/account/logout' - assert_equal 301, @response.status - assert_equal 'http://www.example.com/logout', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com/logout' end end def test_namespace_redirect with_test_routes do get '/private' - assert_equal 301, @response.status - assert_equal 'http://www.example.com/private/index', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com/private/index' end end @@ -586,27 +581,21 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_redirect_modulo with_test_routes do get '/account/modulo/name' - assert_equal 301, @response.status - assert_equal 'http://www.example.com/names', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com/names' end end def test_redirect_proc with_test_routes do get '/account/proc/person' - assert_equal 301, @response.status - assert_equal 'http://www.example.com/people', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com/people' end end def test_redirect_proc_with_request with_test_routes do get '/account/proc_req' - assert_equal 301, @response.status - assert_equal 'http://www.example.com/GET', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com/GET' end end @@ -1203,12 +1192,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - def test_redirect_with_complete_url + def test_redirect_with_complete_url_and_status with_test_routes do get '/account/google' - assert_equal 301, @response.status - assert_equal 'http://www.google.com/', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.google.com/', 302 end end @@ -1216,9 +1203,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest previous_host, self.host = self.host, 'www.example.com:3000' with_test_routes do get '/account/login' - assert_equal 301, @response.status - assert_equal 'http://www.example.com:3000/login', @response.headers['Location'] - assert_equal 'Moved Permanently', @response.body + verify_redirect 'http://www.example.com:3000/login' end ensure self.host = previous_host @@ -1899,8 +1884,18 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - private - def with_test_routes - yield - end +private + def with_test_routes + yield + end + + def verify_redirect(url, status=301) + assert_equal status, @response.status + assert_equal url, @response.headers['Location'] + assert_equal expected_redirect_body(url), @response.body + end + + def expected_redirect_body(url) + %(You are being redirected.) + end end -- 1.7.1 From 195e891954a3664a50db8aaf4ac85b797ce97834 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 9 Aug 2010 14:11:05 +0200 Subject: [PATCH 061/805] form helpers guide: fixes an example --- railties/guides/source/form_helpers.textile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile index 1f1b7d0..146b75d 100644 --- a/railties/guides/source/form_helpers.textile +++ b/railties/guides/source/form_helpers.textile @@ -647,7 +647,7 @@ the +params+ hash will contain {'person' => {'name' => 'Henry'}} -and +params["name"]+ will retrieve the submitted value in the controller. +and +params[:person][:name]+ will retrieve the submitted value in the controller. Hashes can be nested as many levels as required, for example -- 1.7.1 From efb2bd0409c8e9bfd8a5d480169d82622a58197a Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 9 Aug 2010 15:14:00 +0200 Subject: [PATCH 062/805] adds missing requires for Object#try --- actionmailer/lib/action_mailer/deprecated_api.rb | 2 ++ .../action_dispatch/routing/deprecated_mapper.rb | 1 + .../lib/action_dispatch/testing/integration.rb | 1 + .../lib/action_view/helpers/sanitize_helper.rb | 1 + actionpack/test/controller/resources_test.rb | 1 + .../lib/active_record/relation/calculations.rb | 1 + activeresource/lib/active_resource/http_mock.rb | 6 +++++- 7 files changed, 12 insertions(+), 1 deletions(-) diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 0070d8e..7d57feb 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/try' + module ActionMailer # This is the API which is deprecated and is going to be removed on Rails 3.1 release. # Part of the old API will be deprecated after 3.1, for a smoother deprecation process. diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb index 4904f06..e04062c 100644 --- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb +++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/with_options' +require 'active_support/core_ext/object/try' module ActionDispatch module Routing diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 8e58ada..b52795c 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -1,6 +1,7 @@ require 'stringio' require 'uri' require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/core_ext/object/try' require 'rack/test' require 'test/unit/assertions' diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index d5638a6..d82005f 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/object/try' require 'action_controller/vendor/html-scanner' require 'action_view/helpers/tag_helper' diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index a9d1c55..6c8f470 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/object/try' require 'abstract_unit' class ResourcesController < ActionController::Base diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index f8412bc..a679c44 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/object/try' module ActiveRecord module Calculations diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb index f192c53..75425c0 100644 --- a/activeresource/lib/active_resource/http_mock.rb +++ b/activeresource/lib/active_resource/http_mock.rb @@ -123,7 +123,11 @@ module ActiveResource # def post(path, body, headers) # request = ActiveResource::Request.new(:post, path, body, headers) # self.class.requests << request - # self.class.responses.assoc(request).try(:second) || raise(InvalidRequestError.new("No response recorded for #{request}")) + # if response = self.class.responses.assoc(request) + # response[1] + # else + # raise InvalidRequestError.new("No response recorded for #{request}") + # end # end module_eval <<-EOE, __FILE__, __LINE__ + 1 def #{method}(path, #{'body, ' if has_body}headers) -- 1.7.1 From 22cbc3f0fa9ebec6630fdd3e905a0232ee626f23 Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 9 Aug 2010 11:48:31 -0700 Subject: [PATCH 063/805] Improve best_standards_support to use only IE=Edge in development mode --- .../middleware/best_standards_support.rb | 13 +++- railties/lib/rails/application.rb | 2 +- .../config/environments/development.rb.tt | 4 + railties/test/application/routing_test.rb | 96 +++++++++++++------- 4 files changed, 81 insertions(+), 34 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb index df8f776..69adcc4 100644 --- a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb +++ b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb @@ -1,12 +1,21 @@ module ActionDispatch class BestStandardsSupport - def initialize(app) + def initialize(app, type = true) @app = app + + @header = case type + when true + "IE=Edge,chrome=1" + when :builtin + "IE=Edge" + when false + nil + end end def call(env) status, headers, body = @app.call(env) - headers["X-UA-Compatible"] = "IE=Edge,chrome=1" + headers["X-UA-Compatible"] = @header [status, headers, body] end end diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 6622cfd..5b26333 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -205,7 +205,7 @@ module Rails middleware.use ::ActionDispatch::ParamsParser middleware.use ::Rack::MethodOverride middleware.use ::ActionDispatch::Head - middleware.use ::ActionDispatch::BestStandardsSupport if config.action_dispatch.best_standards_support + middleware.use ::ActionDispatch::BestStandardsSupport, config.action_dispatch.best_standards_support if config.action_dispatch.best_standards_support end end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt index 99758df..7616614 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt @@ -19,4 +19,8 @@ # Print deprecation notices to the Rails logger config.active_support.deprecation = :log + + # Only use best-standards-support built into browsers + config.action_dispatch.best_standards_support = :builtin end + diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index a10a39e..febc53b 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -11,19 +11,19 @@ module ApplicationTests extend Rack::Test::Methods end - def app + def app(env = "production") + old_env = ENV["RAILS_ENV"] + @app ||= begin + ENV["RAILS_ENV"] = env require "#{app_path}/config/environment" Rails.application end + ensure + ENV["RAILS_ENV"] = old_env end - test "rails/info/properties" do - get "/rails/info/properties" - assert_equal 200, last_response.status - end - - test "simple controller" do + def simple_controller controller :foo, <<-RUBY class FooController < ApplicationController def index @@ -37,12 +37,42 @@ module ApplicationTests match ':controller(/:action)' end RUBY + end + + test "rails/info/properties in development" do + app("development") + get "/rails/info/properties" + assert_equal 200, last_response.status + end + + test "rails/info/properties in production" do + app("production") + get "/rails/info/properties" + assert_equal 404, last_response.status + end + + test "simple controller" do + simple_controller get '/foo' assert_equal 'foo', last_response.body + end + + test "simple controller in production mode returns best standards" do + simple_controller + + get '/foo' assert_equal "IE=Edge,chrome=1", last_response.headers["X-UA-Compatible"] end + test "simple controller in development mode leaves out Chrome" do + simple_controller + app("development") + + get "/foo" + assert_equal "IE=Edge", last_response.headers["X-UA-Compatible"] + end + test "simple controller with helper" do controller :foo, <<-RUBY class FooController < ApplicationController @@ -147,38 +177,42 @@ module ApplicationTests assert_equal 'admin::foo', last_response.body end - test "reloads routes when configuration is changed" do - controller :foo, <<-RUBY - class FooController < ApplicationController - def bar - render :text => "bar" + {"development" => "baz", "production" => "bar"}.each do |mode, expected| + test "reloads routes when configuration is changed in #{mode}" do + controller :foo, <<-RUBY + class FooController < ApplicationController + def bar + render :text => "bar" + end + + def baz + render :text => "baz" + end end + RUBY - def baz - render :text => "baz" + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do |map| + match 'foo', :to => 'foo#bar' end - end - RUBY + RUBY - app_file 'config/routes.rb', <<-RUBY - AppTemplate::Application.routes.draw do |map| - match 'foo', :to => 'foo#bar' - end - RUBY + app(mode) - get '/foo' - assert_equal 'bar', last_response.body + get '/foo' + assert_equal 'bar', last_response.body - app_file 'config/routes.rb', <<-RUBY - AppTemplate::Application.routes.draw do |map| - match 'foo', :to => 'foo#baz' - end - RUBY + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do |map| + match 'foo', :to => 'foo#baz' + end + RUBY - sleep 0.1 + sleep 0.1 - get '/foo' - assert_equal 'baz', last_response.body + get '/foo' + assert_equal expected, last_response.body + end end test 'resource routing with irrigular inflection' do -- 1.7.1 From f85b206e7a8c56dc00edf1beb20decbc77945b32 Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 9 Aug 2010 12:06:25 -0700 Subject: [PATCH 064/805] rename _snowman to _e --- .../lib/action_view/helpers/form_tag_helper.rb | 2 +- actionpack/test/template/form_helper_test.rb | 2 +- actionpack/test/template/form_tag_helper_test.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 9dac2d4..1ea8704 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -538,7 +538,7 @@ module ActionView def extra_tags_for_form(html_options) snowman_tag = tag(:input, :type => "hidden", - :name => "_snowman", :value => "☃".html_safe) + :name => "_e", :value => "☃".html_safe) method = html_options.delete("method").to_s diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 9086a23..be66710 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -1513,7 +1513,7 @@ class FormHelperTest < ActionView::TestCase def snowman(method = nil) txt = %{
} - txt << %{} + txt << %{} txt << %{} if method txt << %{
} end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 8a0f352..6c85952 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -12,7 +12,7 @@ class FormTagHelperTest < ActionView::TestCase method = options[:method] txt = %{
} - txt << %{} + txt << %{} txt << %{} if method txt << %{
} end -- 1.7.1 From dd7e872e85bce6df43c3c3b6becf9364eb054b42 Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 9 Aug 2010 12:42:09 -0700 Subject: [PATCH 065/805] Properly deprecate register_javascript_include_default and reset_javascript_include_default --- .../lib/action_view/helpers/asset_tag_helper.rb | 12 ++++++++++++ actionpack/test/template/asset_tag_helper_test.rb | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index a3c43d3..1eab306 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -393,6 +393,18 @@ module ActionView @@stylesheet_expansions.merge!(expansions) end + def self.reset_javascript_include_default + ActiveSupport::Deprecation.warn "reset_javascript_include_default is deprecated. Please manipulate " \ + "config.action_view.javascript_expansions[:defaults] directly", caller + self.javascript_expansions[:defaults] = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'] + end + + def self.register_javascript_include_default(*args) + ActiveSupport::Deprecation.warn "register_javascript_include_default is deprecated. Please " \ + "manipulate config.action_view.javascript_expansions[:defaults] directly", caller + self.javascript_expansions[:defaults].concat args + end + # Computes the path to a stylesheet asset in the public stylesheets directory. # If the +source+ filename has no extension, .css will be appended (except for explicit URIs). # Full paths from the document root will be passed through. diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 6d5e489..76ce26e 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -278,6 +278,20 @@ class AssetTagHelperTest < ActionView::TestCase assert_raise(ArgumentError) { javascript_include_tag(:defaults) } end + def test_deprecated_reset_javascript_expansions + ENV["RAILS_ASSET_ID"] = "" + assert_deprecated { ActionView::Helpers::AssetTagHelper.reset_javascript_include_default } + assert_equal JavascriptIncludeToTag["javascript_include_tag(:defaults)"], javascript_include_tag(:defaults) + end + + def test_deprecated_register_javascript_expansions + ENV["RAILS_ASSET_ID"] = "" + assert_deprecated { ActionView::Helpers::AssetTagHelper.reset_javascript_include_default } + assert_deprecated { ActionView::Helpers::AssetTagHelper.register_javascript_include_default("foo") } + result = %(\n\n\n\n\n\n) + assert_equal result, javascript_include_tag(:defaults) + end + def test_stylesheet_path ENV["RAILS_ASSET_ID"] = "" StylePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } -- 1.7.1 From a263a8ffd562b1c59b93ac80fc624afeaf415964 Mon Sep 17 00:00:00 2001 From: Brian Lopez Date: Mon, 9 Aug 2010 15:29:26 -0700 Subject: [PATCH 066/805] update tests for mysql2 support --- Gemfile | 1 + activerecord/Rakefile | 14 +- .../cases/adapters/mysql/active_schema_test.rb | 2 +- .../cases/adapters/mysql2/active_schema_test.rb | 125 ++++++++++ .../test/cases/adapters/mysql2/connection_test.rb | 42 ++++ .../cases/adapters/mysql2/reserved_word_test.rb | 176 +++++++++++++ .../associations/belongs_to_associations_test.rb | 2 +- .../has_and_belongs_to_many_associations_test.rb | 9 +- activerecord/test/cases/base_test.rb | 259 +++++++++++++++++++- activerecord/test/cases/calculations_test.rb | 2 +- activerecord/test/cases/column_definition_test.rb | 34 +++ activerecord/test/cases/defaults_test.rb | 2 +- activerecord/test/cases/migration_test.rb | 12 +- activerecord/test/cases/query_cache_test.rb | 2 +- activerecord/test/cases/schema_dumper_test.rb | 4 +- .../test/connections/native_mysql2/connection.rb | 25 ++ activerecord/test/schema/mysql2_specific_schema.rb | 24 ++ 17 files changed, 712 insertions(+), 23 deletions(-) create mode 100644 activerecord/test/cases/adapters/mysql2/active_schema_test.rb create mode 100644 activerecord/test/cases/adapters/mysql2/connection_test.rb create mode 100644 activerecord/test/cases/adapters/mysql2/reserved_word_test.rb create mode 100644 activerecord/test/connections/native_mysql2/connection.rb create mode 100644 activerecord/test/schema/mysql2_specific_schema.rb diff --git a/Gemfile b/Gemfile index 71dc1f3..b3cb2c5 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,7 @@ platforms :ruby do group :db do gem "pg", ">= 0.9.0" gem "mysql", ">= 2.8.1" + gem "mysql2", :path => 'git://github.com/brianmario/mysql2.git' end end diff --git a/activerecord/Rakefile b/activerecord/Rakefile index 36cd7e3..c1e90cc 100644 --- a/activerecord/Rakefile +++ b/activerecord/Rakefile @@ -24,14 +24,14 @@ def run_without_aborting(*tasks) abort "Errors running #{errors.join(', ')}" if errors.any? end -desc 'Run mysql, sqlite, and postgresql tests by default' +desc 'Run mysql, mysql2, sqlite, and postgresql tests by default' task :default => :test -desc 'Run mysql, sqlite, and postgresql tests' +desc 'Run mysql, mysql2, sqlite, and postgresql tests' task :test do tasks = defined?(JRUBY_VERSION) ? %w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) : - %w(test_mysql test_sqlite3 test_postgresql) + %w(test_mysql test_mysql2 test_sqlite3 test_postgresql) run_without_aborting(*tasks) end @@ -39,15 +39,15 @@ namespace :test do task :isolated do tasks = defined?(JRUBY_VERSION) ? %w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) : - %w(isolated_test_mysql isolated_test_sqlite3 isolated_test_postgresql) + %w(isolated_test_mysql isolated_test_mysql2 isolated_test_sqlite3 isolated_test_postgresql) run_without_aborting(*tasks) end end -%w( mysql postgresql sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter| +%w( mysql mysql2 postgresql sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter| Rake::TestTask.new("test_#{adapter}") { |t| connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}" - adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/] + adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z0-9]+/] t.libs << "test" << connection_path t.test_files = (Dir.glob( "test/cases/**/*_test.rb" ).reject { |x| x =~ /\/adapters\// @@ -59,7 +59,7 @@ end task "isolated_test_#{adapter}" do connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}" - adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/] + adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z0-9]+/] puts [adapter, adapter_short, connection_path].inspect ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')) (Dir["test/cases/**/*_test.rb"].reject { diff --git a/activerecord/test/cases/adapters/mysql/active_schema_test.rb b/activerecord/test/cases/adapters/mysql/active_schema_test.rb index ed4efdc..509baac 100644 --- a/activerecord/test/cases/adapters/mysql/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/active_schema_test.rb @@ -42,7 +42,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase assert_equal "DROP TABLE `people`", drop_table(:people) end - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) def test_create_mysql_database_with_encoding assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8`", create_database(:matt) assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, {:charset => 'latin1'}) diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb new file mode 100644 index 0000000..a83399d --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb @@ -0,0 +1,125 @@ +require "cases/helper" + +class ActiveSchemaTest < ActiveRecord::TestCase + def setup + ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do + alias_method :execute_without_stub, :execute + remove_method :execute + def execute(sql, name = nil) return sql end + end + end + + def teardown + ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do + remove_method :execute + alias_method :execute, :execute_without_stub + end + end + + def test_add_index + # add_index calls index_name_exists? which can't work since execute is stubbed + ActiveRecord::ConnectionAdapters::Mysql2Adapter.send(:define_method, :index_name_exists?) do |*| + false + end + expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`)" + assert_equal expected, add_index(:people, :last_name, :length => nil) + + expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`(10))" + assert_equal expected, add_index(:people, :last_name, :length => 10) + + expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(15))" + assert_equal expected, add_index(:people, [:last_name, :first_name], :length => 15) + + expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`)" + assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15}) + + expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(10))" + assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15, :first_name => 10}) + ActiveRecord::ConnectionAdapters::Mysql2Adapter.send(:remove_method, :index_name_exists?) + end + + def test_drop_table + assert_equal "DROP TABLE `people`", drop_table(:people) + end + + if current_adapter?(:Mysql2Adapter) + def test_create_mysql_database_with_encoding + assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8`", create_database(:matt) + assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, {:charset => 'latin1'}) + assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `big5` COLLATE `big5_chinese_ci`", create_database(:matt_aimonetti, {:charset => :big5, :collation => :big5_chinese_ci}) + end + + def test_recreate_mysql_database_with_encoding + create_database(:luca, {:charset => 'latin1'}) + assert_equal "CREATE DATABASE `luca` DEFAULT CHARACTER SET `latin1`", recreate_database(:luca, {:charset => 'latin1'}) + end + end + + def test_add_column + assert_equal "ALTER TABLE `people` ADD `last_name` varchar(255)", add_column(:people, :last_name, :string) + end + + def test_add_column_with_limit + assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32) + end + + def test_drop_table_with_specific_database + assert_equal "DROP TABLE `otherdb`.`people`", drop_table('otherdb.people') + end + + def test_add_timestamps + with_real_execute do + begin + ActiveRecord::Base.connection.create_table :delete_me do |t| + end + ActiveRecord::Base.connection.add_timestamps :delete_me + assert column_present?('delete_me', 'updated_at', 'datetime') + assert column_present?('delete_me', 'created_at', 'datetime') + ensure + ActiveRecord::Base.connection.drop_table :delete_me rescue nil + end + end + end + + def test_remove_timestamps + with_real_execute do + begin + ActiveRecord::Base.connection.create_table :delete_me do |t| + t.timestamps + end + ActiveRecord::Base.connection.remove_timestamps :delete_me + assert !column_present?('delete_me', 'updated_at', 'datetime') + assert !column_present?('delete_me', 'created_at', 'datetime') + ensure + ActiveRecord::Base.connection.drop_table :delete_me rescue nil + end + end + end + + private + def with_real_execute + #we need to actually modify some data, so we make execute point to the original method + ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do + alias_method :execute_with_stub, :execute + remove_method :execute + alias_method :execute, :execute_without_stub + end + yield + ensure + #before finishing, we restore the alias to the mock-up method + ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do + remove_method :execute + alias_method :execute, :execute_with_stub + end + end + + + def method_missing(method_symbol, *arguments) + ActiveRecord::Base.connection.send(method_symbol, *arguments) + end + + def column_present?(table_name, column_name, type) + results = ActiveRecord::Base.connection.select_all("SHOW FIELDS FROM #{table_name} LIKE '#{column_name}'") + results.first && results.first['Type'] == type + end +end diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb new file mode 100644 index 0000000..b973da6 --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -0,0 +1,42 @@ +require "cases/helper" + +class MysqlConnectionTest < ActiveRecord::TestCase + def setup + super + @connection = ActiveRecord::Base.connection + end + + def test_no_automatic_reconnection_after_timeout + assert @connection.active? + @connection.update('set @@wait_timeout=1') + sleep 2 + assert !@connection.active? + end + + def test_successful_reconnection_after_timeout_with_manual_reconnect + assert @connection.active? + @connection.update('set @@wait_timeout=1') + sleep 2 + @connection.reconnect! + assert @connection.active? + end + + def test_successful_reconnection_after_timeout_with_verify + assert @connection.active? + @connection.update('set @@wait_timeout=1') + sleep 2 + @connection.verify! + assert @connection.active? + end + + private + + def run_without_connection + original_connection = ActiveRecord::Base.remove_connection + begin + yield original_connection + ensure + ActiveRecord::Base.establish_connection(original_connection) + end + end +end diff --git a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb new file mode 100644 index 0000000..90d8b0d --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb @@ -0,0 +1,176 @@ +require "cases/helper" + +class Group < ActiveRecord::Base + Group.table_name = 'group' + belongs_to :select, :class_name => 'Select' + has_one :values +end + +class Select < ActiveRecord::Base + Select.table_name = 'select' + has_many :groups +end + +class Values < ActiveRecord::Base + Values.table_name = 'values' +end + +class Distinct < ActiveRecord::Base + Distinct.table_name = 'distinct' + has_and_belongs_to_many :selects + has_many :values, :through => :groups +end + +# a suite of tests to ensure the ConnectionAdapters#MysqlAdapter can handle tables with +# reserved word names (ie: group, order, values, etc...) +class MysqlReservedWordTest < ActiveRecord::TestCase + def setup + @connection = ActiveRecord::Base.connection + + # we call execute directly here (and do similar below) because ActiveRecord::Base#create_table() + # will fail with these table names if these test cases fail + + create_tables_directly 'group'=>'id int auto_increment primary key, `order` varchar(255), select_id int', + 'select'=>'id int auto_increment primary key', + 'values'=>'id int auto_increment primary key, group_id int', + 'distinct'=>'id int auto_increment primary key', + 'distincts_selects'=>'distinct_id int, select_id int' + end + + def teardown + drop_tables_directly ['group', 'select', 'values', 'distinct', 'distincts_selects', 'order'] + end + + # create tables with reserved-word names and columns + def test_create_tables + assert_nothing_raised { + @connection.create_table :order do |t| + t.column :group, :string + end + } + end + + # rename tables with reserved-word names + def test_rename_tables + assert_nothing_raised { @connection.rename_table(:group, :order) } + end + + # alter column with a reserved-word name in a table with a reserved-word name + def test_change_columns + assert_nothing_raised { @connection.change_column_default(:group, :order, 'whatever') } + #the quoting here will reveal any double quoting issues in change_column's interaction with the column method in the adapter + assert_nothing_raised { @connection.change_column('group', 'order', :Int, :default => 0) } + assert_nothing_raised { @connection.rename_column(:group, :order, :values) } + end + + # dump structure of table with reserved word name + def test_structure_dump + assert_nothing_raised { @connection.structure_dump } + end + + # introspect table with reserved word name + def test_introspect + assert_nothing_raised { @connection.columns(:group) } + assert_nothing_raised { @connection.indexes(:group) } + end + + #fixtures + self.use_instantiated_fixtures = true + self.use_transactional_fixtures = false + + #fixtures :group + + def test_fixtures + f = create_test_fixtures :select, :distinct, :group, :values, :distincts_selects + + assert_nothing_raised { + f.each do |x| + x.delete_existing_fixtures + end + } + + assert_nothing_raised { + f.each do |x| + x.insert_fixtures + end + } + end + + #activerecord model class with reserved-word table name + def test_activerecord_model + create_test_fixtures :select, :distinct, :group, :values, :distincts_selects + x = nil + assert_nothing_raised { x = Group.new } + x.order = 'x' + assert_nothing_raised { x.save } + x.order = 'y' + assert_nothing_raised { x.save } + assert_nothing_raised { y = Group.find_by_order('y') } + assert_nothing_raised { y = Group.find(1) } + x = Group.find(1) + end + + # has_one association with reserved-word table name + def test_has_one_associations + create_test_fixtures :select, :distinct, :group, :values, :distincts_selects + v = nil + assert_nothing_raised { v = Group.find(1).values } + assert_equal 2, v.id + end + + # belongs_to association with reserved-word table name + def test_belongs_to_associations + create_test_fixtures :select, :distinct, :group, :values, :distincts_selects + gs = nil + assert_nothing_raised { gs = Select.find(2).groups } + assert_equal gs.length, 2 + assert(gs.collect{|x| x.id}.sort == [2, 3]) + end + + # has_and_belongs_to_many with reserved-word table name + def test_has_and_belongs_to_many + create_test_fixtures :select, :distinct, :group, :values, :distincts_selects + s = nil + assert_nothing_raised { s = Distinct.find(1).selects } + assert_equal s.length, 2 + assert(s.collect{|x|x.id}.sort == [1, 2]) + end + + # activerecord model introspection with reserved-word table and column names + def test_activerecord_introspection + assert_nothing_raised { Group.table_exists? } + assert_nothing_raised { Group.columns } + end + + # Calculations + def test_calculations_work_with_reserved_words + assert_nothing_raised { Group.count } + end + + def test_associations_work_with_reserved_words + assert_nothing_raised { Select.find(:all, :include => [:groups]) } + end + + #the following functions were added to DRY test cases + + private + # custom fixture loader, uses Fixtures#create_fixtures and appends base_path to the current file's path + def create_test_fixtures(*fixture_names) + Fixtures.create_fixtures(FIXTURES_ROOT + "/reserved_words", fixture_names) + end + + # custom drop table, uses execute on connection to drop a table if it exists. note: escapes table_name + def drop_tables_directly(table_names, connection = @connection) + table_names.each do |name| + connection.execute("DROP TABLE IF EXISTS `#{name}`") + end + end + + # custom create table, uses execute on connection to create a table, note: escapes table_name, does NOT escape columns + def create_tables_directly (tables, connection = @connection) + tables.each do |table_name, column_properties| + connection.execute("CREATE TABLE `#{table_name}` ( #{column_properties} )") + end + end + +end diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 0464338..a1ce9b1 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -32,7 +32,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_belongs_to_with_primary_key_joins_on_correct_column sql = Client.joins(:firm_with_primary_key).to_sql - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) assert_no_match(/`firm_with_primary_keys_companies`\.`id`/, sql) assert_match(/`firm_with_primary_keys_companies`\.`name`/, sql) elsif current_adapter?(:OracleAdapter) 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 6b4a1d9..ed7d9a7 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 @@ -109,8 +109,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase record = con.select_rows(sql).last assert_not_nil record[2] assert_not_nil record[3] - assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2] - assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3] + if current_adapter?(:Mysql2Adapter) + assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2].to_s(:db) + assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3].to_s(:db) + else + assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2] + assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3] + end end def test_should_record_timestamp_for_join_table_only_if_timestamp_should_be_recorded diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 56ec4ca..2ea636a 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -52,6 +52,263 @@ class BasicsTest < ActiveRecord::TestCase assert Topic.table_exists? end + def test_set_attributes + topic = Topic.find(1) + topic.attributes = { "title" => "Budget", "author_name" => "Jason" } + topic.save + assert_equal("Budget", topic.title) + assert_equal("Jason", topic.author_name) + assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address) + end + + def test_set_attributes_without_hash + topic = Topic.new + assert_nothing_raised { topic.attributes = '' } + end + + def test_integers_as_nil + test = AutoId.create('value' => '') + assert_nil AutoId.find(test.id).value + end + + def test_set_attributes_with_block + topic = Topic.new do |t| + t.title = "Budget" + t.author_name = "Jason" + end + + assert_equal("Budget", topic.title) + assert_equal("Jason", topic.author_name) + end + + def test_respond_to? + topic = Topic.find(1) + assert_respond_to topic, "title" + assert_respond_to topic, "title?" + assert_respond_to topic, "title=" + assert_respond_to topic, :title + assert_respond_to topic, :title? + assert_respond_to topic, :title= + assert_respond_to topic, "author_name" + assert_respond_to topic, "attribute_names" + assert !topic.respond_to?("nothingness") + assert !topic.respond_to?(:nothingness) + end + + def test_array_content + topic = Topic.new + topic.content = %w( one two three ) + topic.save + + assert_equal(%w( one two three ), Topic.find(topic.id).content) + end + + def test_read_attributes_before_type_cast + category = Category.new({:name=>"Test categoty", :type => nil}) + category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil} + assert_equal category_attrs , category.attributes_before_type_cast + end + + if current_adapter?(:MysqlAdapter) + def test_read_attributes_before_type_cast_on_boolean + bool = Booleantest.create({ "value" => false }) + assert_equal "0", bool.reload.attributes_before_type_cast["value"] + end + end + + if current_adapter?(:Mysql2Adapter) + def test_read_attributes_before_type_cast_on_boolean + bool = Booleantest.create({ "value" => false }) + assert_equal 0, bool.reload.attributes_before_type_cast["value"] + end + end + + def test_read_attributes_before_type_cast_on_datetime + developer = Developer.find(:first) + # Oracle adapter returns Time before type cast + if current_adapter?(:OracleAdapter) + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) + + developer.created_at = "345643456" + assert_equal developer.created_at_before_type_cast, "345643456" + assert_equal developer.created_at, nil + + developer.created_at = "2010-03-21T21:23:32+01:00" + assert_equal developer.created_at_before_type_cast, "2010-03-21T21:23:32+01:00" + assert_equal developer.created_at, Time.parse("2010-03-21T21:23:32+01:00") + elsif current_adapter?(:Mysql2Adapter) + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) + else + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"] + end + end + + def test_hash_content + topic = Topic.new + topic.content = { "one" => 1, "two" => 2 } + topic.save + + assert_equal 2, Topic.find(topic.id).content["two"] + + topic.content_will_change! + topic.content["three"] = 3 + topic.save + + assert_equal 3, Topic.find(topic.id).content["three"] + end + + def test_update_array_content + topic = Topic.new + topic.content = %w( one two three ) + + topic.content.push "four" + assert_equal(%w( one two three four ), topic.content) + + topic.save + + topic = Topic.find(topic.id) + topic.content << "five" + assert_equal(%w( one two three four five ), topic.content) + end + + def test_case_sensitive_attributes_hash + # DB2 is not case-sensitive + return true if current_adapter?(:DB2Adapter) + + assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.find(:first).attributes + end + + def test_hashes_not_mangled + new_topic = { :title => "New Topic" } + new_topic_values = { :title => "AnotherTopic" } + + topic = Topic.new(new_topic) + assert_equal new_topic[:title], topic.title + + topic.attributes= new_topic_values + assert_equal new_topic_values[:title], topic.title + end + + def test_create_through_factory + topic = Topic.create("title" => "New Topic") + topicReloaded = Topic.find(topic.id) + assert_equal(topic, topicReloaded) + end + + def test_write_attribute + topic = Topic.new + topic.send(:write_attribute, :title, "Still another topic") + assert_equal "Still another topic", topic.title + + topic.send(:write_attribute, "title", "Still another topic: part 2") + assert_equal "Still another topic: part 2", topic.title + end + + def test_read_attribute + topic = Topic.new + topic.title = "Don't change the topic" + assert_equal "Don't change the topic", topic.send(:read_attribute, "title") + assert_equal "Don't change the topic", topic["title"] + + assert_equal "Don't change the topic", topic.send(:read_attribute, :title) + assert_equal "Don't change the topic", topic[:title] + end + + def test_read_attribute_when_false + topic = topics(:first) + topic.approved = false + assert !topic.approved?, "approved should be false" + topic.approved = "false" + assert !topic.approved?, "approved should be false" + end + + def test_read_attribute_when_true + topic = topics(:first) + topic.approved = true + assert topic.approved?, "approved should be true" + topic.approved = "true" + assert topic.approved?, "approved should be true" + end + + def test_read_write_boolean_attribute + topic = Topic.new + # puts "" + # puts "New Topic" + # puts topic.inspect + topic.approved = "false" + # puts "Expecting false" + # puts topic.inspect + assert !topic.approved?, "approved should be false" + topic.approved = "false" + # puts "Expecting false" + # puts topic.inspect + assert !topic.approved?, "approved should be false" + topic.approved = "true" + # puts "Expecting true" + # puts topic.inspect + assert topic.approved?, "approved should be true" + topic.approved = "true" + # puts "Expecting true" + # puts topic.inspect + assert topic.approved?, "approved should be true" + # puts "" + end + + def test_query_attribute_string + [nil, "", " "].each do |value| + assert_equal false, Topic.new(:author_name => value).author_name? + end + + assert_equal true, Topic.new(:author_name => "Name").author_name? + end + + def test_query_attribute_number + [nil, 0, "0"].each do |value| + assert_equal false, Developer.new(:salary => value).salary? + end + + assert_equal true, Developer.new(:salary => 1).salary? + assert_equal true, Developer.new(:salary => "1").salary? + end + + def test_query_attribute_boolean + [nil, "", false, "false", "f", 0].each do |value| + assert_equal false, Topic.new(:approved => value).approved? + end + + [true, "true", "1", 1].each do |value| + assert_equal true, Topic.new(:approved => value).approved? + end + end + + def test_query_attribute_with_custom_fields + object = Company.find_by_sql(<<-SQL).first + SELECT c1.*, c2.ruby_type as string_value, c2.rating as int_value + FROM companies c1, companies c2 + WHERE c1.firm_id = c2.id + AND c1.id = 2 + SQL + + assert_equal "Firm", object.string_value + assert object.string_value? + + object.string_value = " " + assert !object.string_value? + + assert_equal 1, object.int_value.to_i + assert object.int_value? + + object.int_value = "0" + assert !object.int_value? + end + + def test_non_attribute_access_and_assignment + topic = Topic.new + assert !topic.respond_to?("mumbo") + assert_raise(NoMethodError) { topic.mumbo } + assert_raise(NoMethodError) { topic.mumbo = 5 } + end + def test_preserving_date_objects if current_adapter?(:SybaseAdapter) # Sybase ctlib does not (yet?) support the date type; use datetime instead. @@ -284,7 +541,7 @@ class BasicsTest < ActiveRecord::TestCase end - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) def test_update_all_with_order_and_limit assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC') end diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 2c9d23c..afef313 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -325,7 +325,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_from_option_with_specified_index - if Edge.connection.adapter_name == 'MySQL' + if Edge.connection.adapter_name == 'MySQL' or Edge.connection.adapter_name == 'Mysql2' assert_equal Edge.count(:all), Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)') assert_equal Edge.count(:all, :conditions => 'sink_id < 5'), Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)', :conditions => 'sink_id < 5') diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb index b576734..cc6a6b4 100644 --- a/activerecord/test/cases/column_definition_test.rb +++ b/activerecord/test/cases/column_definition_test.rb @@ -68,6 +68,40 @@ class ColumnDefinitionTest < ActiveRecord::TestCase end end + if current_adapter?(:Mysql2Adapter) + def test_should_set_default_for_mysql_binary_data_types + binary_column = ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", "a", "binary(1)") + assert_equal "a", binary_column.default + + varbinary_column = ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", "a", "varbinary(1)") + assert_equal "a", varbinary_column.default + end + + def test_should_not_set_default_for_blob_and_text_data_types + assert_raise ArgumentError do + ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", "a", "blob") + end + + assert_raise ArgumentError do + ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", "Hello", "text") + end + + text_column = ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", nil, "text") + assert_equal nil, text_column.default + + not_null_text_column = ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", nil, "text", false) + assert_equal "", not_null_text_column.default + end + + def test_has_default_should_return_false_for_blog_and_test_data_types + blob_column = ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", nil, "blob") + assert !blob_column.has_default? + + text_column = ActiveRecord::ConnectionAdapters::Mysql2Column.new("title", nil, "text") + assert !text_column.has_default? + end + end + if current_adapter?(:PostgreSQLAdapter) def test_bigint_column_should_map_to_integer bigint_column = ActiveRecord::ConnectionAdapters::PostgreSQLColumn.new('number', nil, "bigint") diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb index ef29422..0e90128 100644 --- a/activerecord/test/cases/defaults_test.rb +++ b/activerecord/test/cases/defaults_test.rb @@ -39,7 +39,7 @@ class DefaultTest < ActiveRecord::TestCase end end -if current_adapter?(:MysqlAdapter) +if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) class DefaultsTestWithoutTransactionalFixtures < ActiveRecord::TestCase # ActiveRecord::Base#create! (and #save and other related methods) will # open a new transaction. When in transactional fixtures mode, this will diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 2c3fc46..0cf3979 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -256,7 +256,7 @@ if ActiveRecord::Base.connection.supports_migrations? def test_create_table_with_defaults # MySQL doesn't allow defaults on TEXT or BLOB columns. - mysql = current_adapter?(:MysqlAdapter) + mysql = current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter) Person.connection.create_table :testings do |t| t.column :one, :string, :default => "hello" @@ -313,7 +313,7 @@ if ActiveRecord::Base.connection.supports_migrations? assert_equal 'integer', four.sql_type assert_equal 'bigint', eight.sql_type assert_equal 'integer', eleven.sql_type - elsif current_adapter?(:MysqlAdapter) + elsif current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) assert_match 'int(11)', default.sql_type assert_match 'tinyint', one.sql_type assert_match 'int', four.sql_type @@ -581,7 +581,7 @@ if ActiveRecord::Base.connection.supports_migrations? assert_kind_of BigDecimal, bob.wealth end - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) def test_unabstracted_database_dependent_types Person.delete_all @@ -621,7 +621,7 @@ if ActiveRecord::Base.connection.supports_migrations? assert !Person.column_methods_hash.include?(:last_name) end - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) def testing_table_for_positioning Person.connection.create_table :testings, :id => false do |t| t.column :first, :integer @@ -1447,7 +1447,7 @@ if ActiveRecord::Base.connection.supports_migrations? columns = Person.connection.columns(:binary_testings) data_column = columns.detect { |c| c.name == "data" } - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) assert_equal '', data_column.default else assert_nil data_column.default @@ -1748,7 +1748,7 @@ if ActiveRecord::Base.connection.supports_migrations? end def integer_column - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) 'int(11)' elsif current_adapter?(:OracleAdapter) 'NUMBER(38)' diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index f0d97a0..594db1d 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -57,7 +57,7 @@ class QueryCacheTest < ActiveRecord::TestCase # Oracle adapter returns count() as Fixnum or Float if current_adapter?(:OracleAdapter) assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") - elsif current_adapter?(:SQLite3Adapter) && SQLite3::Version::VERSION > '1.2.5' + elsif current_adapter?(:SQLite3Adapter) && SQLite3::Version::VERSION > '1.2.5' or current_adapter?(:Mysql2Adapter) # Future versions of the sqlite3 adapter will return numeric assert_instance_of Fixnum, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 1c43e3c..66446b6 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -93,7 +93,7 @@ class SchemaDumperTest < ActiveRecord::TestCase assert_match %r{c_int_4.*}, output assert_no_match %r{c_int_4.*:limit}, output - elsif current_adapter?(:MysqlAdapter) + elsif current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) assert_match %r{c_int_1.*:limit => 1}, output assert_match %r{c_int_2.*:limit => 2}, output assert_match %r{c_int_3.*:limit => 3}, output @@ -169,7 +169,7 @@ class SchemaDumperTest < ActiveRecord::TestCase assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved" end - if current_adapter?(:MysqlAdapter) + if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) def test_schema_dump_should_not_add_default_value_for_mysql_text_field output = standard_dump assert_match %r{t.text\s+"body",\s+:null => false$}, output diff --git a/activerecord/test/connections/native_mysql2/connection.rb b/activerecord/test/connections/native_mysql2/connection.rb new file mode 100644 index 0000000..c6f198b --- /dev/null +++ b/activerecord/test/connections/native_mysql2/connection.rb @@ -0,0 +1,25 @@ +print "Using native Mysql2\n" +require_dependency 'models/course' +require 'logger' + +ActiveRecord::Base.logger = Logger.new("debug.log") + +# GRANT ALL PRIVILEGES ON activerecord_unittest.* to 'rails'@'localhost'; +# GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost'; + +ActiveRecord::Base.configurations = { + 'arunit' => { + :adapter => 'mysql2', + :username => 'rails', + :encoding => 'utf8', + :database => 'activerecord_unittest', + }, + 'arunit2' => { + :adapter => 'mysql2', + :username => 'rails', + :database => 'activerecord_unittest2' + } +} + +ActiveRecord::Base.establish_connection 'arunit' +Course.establish_connection 'arunit2' diff --git a/activerecord/test/schema/mysql2_specific_schema.rb b/activerecord/test/schema/mysql2_specific_schema.rb new file mode 100644 index 0000000..c78d99f --- /dev/null +++ b/activerecord/test/schema/mysql2_specific_schema.rb @@ -0,0 +1,24 @@ +ActiveRecord::Schema.define do + create_table :binary_fields, :force => true, :options => 'CHARACTER SET latin1' do |t| + t.binary :tiny_blob, :limit => 255 + t.binary :normal_blob, :limit => 65535 + t.binary :medium_blob, :limit => 16777215 + t.binary :long_blob, :limit => 2147483647 + t.text :tiny_text, :limit => 255 + t.text :normal_text, :limit => 65535 + t.text :medium_text, :limit => 16777215 + t.text :long_text, :limit => 2147483647 + end + + ActiveRecord::Base.connection.execute <<-SQL +DROP PROCEDURE IF EXISTS ten; +SQL + + ActiveRecord::Base.connection.execute <<-SQL +CREATE PROCEDURE ten() SQL SECURITY INVOKER +BEGIN + select 10; +END +SQL + +end -- 1.7.1 From 98384b1ce8c55331916e90961b276666f6960d06 Mon Sep 17 00:00:00 2001 From: Brian Lopez Date: Mon, 2 Aug 2010 01:58:23 -0700 Subject: [PATCH 067/805] typo --- Gemfile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Gemfile b/Gemfile index b3cb2c5..d594d20 100644 --- a/Gemfile +++ b/Gemfile @@ -35,7 +35,7 @@ platforms :ruby do group :db do gem "pg", ">= 0.9.0" gem "mysql", ">= 2.8.1" - gem "mysql2", :path => 'git://github.com/brianmario/mysql2.git' + gem "mysql2", :git => 'git://github.com/brianmario/mysql2.git' end end -- 1.7.1 From 3ccf3504d28d5c937051578c41eee29ed18b4d02 Mon Sep 17 00:00:00 2001 From: Brian Lopez Date: Mon, 2 Aug 2010 15:11:00 -0700 Subject: [PATCH 068/805] skip the before_type_cast_on_datetime test entirely for mysql2 --- activerecord/test/cases/base_test.rb | 35 +++++++++++++++++---------------- 1 files changed, 18 insertions(+), 17 deletions(-) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 2ea636a..87ca6f0 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -123,23 +123,24 @@ class BasicsTest < ActiveRecord::TestCase end end - def test_read_attributes_before_type_cast_on_datetime - developer = Developer.find(:first) - # Oracle adapter returns Time before type cast - if current_adapter?(:OracleAdapter) - assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) - - developer.created_at = "345643456" - assert_equal developer.created_at_before_type_cast, "345643456" - assert_equal developer.created_at, nil - - developer.created_at = "2010-03-21T21:23:32+01:00" - assert_equal developer.created_at_before_type_cast, "2010-03-21T21:23:32+01:00" - assert_equal developer.created_at, Time.parse("2010-03-21T21:23:32+01:00") - elsif current_adapter?(:Mysql2Adapter) - assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) - else - assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"] + unless current_adapter?(:Mysql2Adapter) + def test_read_attributes_before_type_cast_on_datetime + developer = Developer.find(:first) + # Oracle adapter returns Time before type cast + if current_adapter?(:OracleAdapter) + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) + + developer.created_at = "345643456" + assert_equal developer.created_at_before_type_cast, "345643456" + assert_equal developer.created_at, nil + + developer.created_at = "2010-03-21T21:23:32+01:00" + assert_equal developer.created_at_before_type_cast, "2010-03-21T21:23:32+01:00" + assert_equal developer.created_at, Time.parse("2010-03-21T21:23:32+01:00") + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) + else + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"] + end end end -- 1.7.1 From b02751c961d76b74f19a00929d162b8e15b43063 Mon Sep 17 00:00:00 2001 From: Brian Lopez Date: Mon, 9 Aug 2010 12:50:09 -0700 Subject: [PATCH 069/805] ignore this test for mysql2 --- activerecord/test/cases/attribute_methods_test.rb | 32 +++++++++++---------- 1 files changed, 17 insertions(+), 15 deletions(-) diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index d20b762..2c069cd 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -106,21 +106,23 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_read_attributes_before_type_cast_on_datetime - developer = Developer.find(:first) - # Oracle adapter returns Time before type cast - unless current_adapter?(:OracleAdapter) - assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"] - else - assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) + unless current_adapter?(:Mysql2Adapter) + def test_read_attributes_before_type_cast_on_datetime + developer = Developer.find(:first) + # Oracle adapter returns Time before type cast + unless current_adapter?(:OracleAdapter) + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"] + else + assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db) - developer.created_at = "345643456" - assert_equal developer.created_at_before_type_cast, "345643456" - assert_equal developer.created_at, nil + developer.created_at = "345643456" + assert_equal developer.created_at_before_type_cast, "345643456" + assert_equal developer.created_at, nil - developer.created_at = "2010-03-21T21:23:32+01:00" - assert_equal developer.created_at_before_type_cast, "2010-03-21T21:23:32+01:00" - assert_equal developer.created_at, Time.parse("2010-03-21T21:23:32+01:00") + developer.created_at = "2010-03-21T21:23:32+01:00" + assert_equal developer.created_at_before_type_cast, "2010-03-21T21:23:32+01:00" + assert_equal developer.created_at, Time.parse("2010-03-21T21:23:32+01:00") + end end end -- 1.7.1 From 2d681838c022b700decffd136c7e8092d6351645 Mon Sep 17 00:00:00 2001 From: Brian Lopez Date: Mon, 9 Aug 2010 14:52:00 -0700 Subject: [PATCH 070/805] move mysql2 adapter into core --- .../connection_adapters/mysql2_adapter.rb | 639 ++++++++++++++++++++ 1 files changed, 639 insertions(+), 0 deletions(-) create mode 100644 activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb new file mode 100644 index 0000000..5687597 --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -0,0 +1,639 @@ +# encoding: utf-8 + +require 'mysql2' unless defined? Mysql2 + +module ActiveRecord + class Base + def self.mysql2_connection(config) + config[:username] = 'root' if config[:username].nil? + client = Mysql2::Client.new(config.symbolize_keys) + options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0] + ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config) + end + end + + module ConnectionAdapters + class Mysql2Column < Column + BOOL = "tinyint(1)" + def extract_default(default) + if sql_type =~ /blob/i || type == :text + if default.blank? + return null ? nil : '' + else + raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}" + end + elsif missing_default_forged_as_empty_string?(default) + nil + else + super + end + end + + def has_default? + return false if sql_type =~ /blob/i || type == :text #mysql forbids defaults on blob and text columns + super + end + + # Returns the Ruby class that corresponds to the abstract data type. + def klass + case type + when :integer then Fixnum + when :float then Float + when :decimal then BigDecimal + when :datetime then Time + when :date then Date + when :timestamp then Time + when :time then Time + when :text, :string then String + when :binary then String + when :boolean then Object + end + end + + def type_cast(value) + return nil if value.nil? + case type + when :string then value + when :text then value + when :integer then value.to_i rescue value ? 1 : 0 + when :float then value.to_f # returns self if it's already a Float + when :decimal then self.class.value_to_decimal(value) + when :datetime, :timestamp then value.class == Time ? value : self.class.string_to_time(value) + when :time then value.class == Time ? value : self.class.string_to_dummy_time(value) + when :date then value.class == Date ? value : self.class.string_to_date(value) + when :binary then value + when :boolean then self.class.value_to_boolean(value) + else value + end + end + + def type_cast_code(var_name) + case type + when :string then nil + when :text then nil + when :integer then "#{var_name}.to_i rescue #{var_name} ? 1 : 0" + when :float then "#{var_name}.to_f" + when :decimal then "#{self.class.name}.value_to_decimal(#{var_name})" + when :datetime, :timestamp then "#{var_name}.class == Time ? #{var_name} : #{self.class.name}.string_to_time(#{var_name})" + when :time then "#{var_name}.class == Time ? #{var_name} : #{self.class.name}.string_to_dummy_time(#{var_name})" + when :date then "#{var_name}.class == Date ? #{var_name} : #{self.class.name}.string_to_date(#{var_name})" + when :binary then nil + when :boolean then "#{self.class.name}.value_to_boolean(#{var_name})" + else nil + end + end + + private + def simplified_type(field_type) + return :boolean if Mysql2Adapter.emulate_booleans && field_type.downcase.index(BOOL) + return :string if field_type =~ /enum/i or field_type =~ /set/i + return :integer if field_type =~ /year/i + return :binary if field_type =~ /bit/i + super + end + + def extract_limit(sql_type) + case sql_type + when /blob|text/i + case sql_type + when /tiny/i + 255 + when /medium/i + 16777215 + when /long/i + 2147483647 # mysql only allows 2^31-1, not 2^32-1, somewhat inconsistently with the tiny/medium/normal cases + else + super # we could return 65535 here, but we leave it undecorated by default + end + when /^bigint/i; 8 + when /^int/i; 4 + when /^mediumint/i; 3 + when /^smallint/i; 2 + when /^tinyint/i; 1 + else + super + end + end + + # MySQL misreports NOT NULL column default when none is given. + # We can't detect this for columns which may have a legitimate '' + # default (string) but we can for others (integer, datetime, boolean, + # and the rest). + # + # Test whether the column has default '', is not null, and is not + # a type allowing default ''. + def missing_default_forged_as_empty_string?(default) + type != :string && !null && default == '' + end + end + + class Mysql2Adapter < AbstractAdapter + cattr_accessor :emulate_booleans + self.emulate_booleans = true + + ADAPTER_NAME = 'Mysql2' + PRIMARY = "PRIMARY" + + LOST_CONNECTION_ERROR_MESSAGES = [ + "Server shutdown in progress", + "Broken pipe", + "Lost connection to MySQL server during query", + "MySQL server has gone away" ] + + QUOTED_TRUE, QUOTED_FALSE = '1', '0' + + NATIVE_DATABASE_TYPES = { + :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY", + :string => { :name => "varchar", :limit => 255 }, + :text => { :name => "text" }, + :integer => { :name => "int", :limit => 4 }, + :float => { :name => "float" }, + :decimal => { :name => "decimal" }, + :datetime => { :name => "datetime" }, + :timestamp => { :name => "datetime" }, + :time => { :name => "time" }, + :date => { :name => "date" }, + :binary => { :name => "blob" }, + :boolean => { :name => "tinyint", :limit => 1 } + } + + def initialize(connection, logger, connection_options, config) + super(connection, logger) + @connection_options, @config = connection_options, config + @quoted_column_names, @quoted_table_names = {}, {} + configure_connection + end + + def adapter_name + ADAPTER_NAME + end + + def supports_migrations? + true + end + + def supports_primary_key? + true + end + + def supports_savepoints? + true + end + + def native_database_types + NATIVE_DATABASE_TYPES + end + + # QUOTING ================================================== + + def quote(value, column = nil) + if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary) + s = column.class.string_to_binary(value).unpack("H*")[0] + "x'#{s}'" + elsif value.kind_of?(BigDecimal) + value.to_s("F") + else + super + end + end + + def quote_column_name(name) #:nodoc: + @quoted_column_names[name] ||= "`#{name}`" + end + + def quote_table_name(name) #:nodoc: + @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`') + end + + def quote_string(string) + @connection.escape(string) + end + + def quoted_true + QUOTED_TRUE + end + + def quoted_false + QUOTED_FALSE + end + + # REFERENTIAL INTEGRITY ==================================== + + def disable_referential_integrity(&block) #:nodoc: + old = select_value("SELECT @@FOREIGN_KEY_CHECKS") + + begin + update("SET FOREIGN_KEY_CHECKS = 0") + yield + ensure + update("SET FOREIGN_KEY_CHECKS = #{old}") + end + end + + # CONNECTION MANAGEMENT ==================================== + + def active? + return false unless @connection + @connection.query 'select 1' + true + rescue Mysql2::Error + false + end + + def reconnect! + disconnect! + connect + end + + # this is set to true in 2.3, but we don't want it to be + def requires_reloading? + false + end + + def disconnect! + unless @connection.nil? + @connection.close + @connection = nil + end + end + + def reset! + disconnect! + connect + end + + # DATABASE STATEMENTS ====================================== + + # FIXME: re-enable the following once a "better" query_cache solution is in core + # + # The overrides below perform much better than the originals in AbstractAdapter + # because we're able to take advantage of mysql2's lazy-loading capabilities + # + # # Returns a record hash with the column names as keys and column values + # # as values. + # def select_one(sql, name = nil) + # result = execute(sql, name) + # result.each(:as => :hash) do |r| + # return r + # end + # end + # + # # Returns a single value from a record + # def select_value(sql, name = nil) + # result = execute(sql, name) + # if first = result.first + # first.first + # end + # end + # + # # Returns an array of the values of the first column in a select: + # # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3] + # def select_values(sql, name = nil) + # execute(sql, name).map { |row| row.first } + # end + + # Returns an array of arrays containing the field values. + # Order is the same as that returned by +columns+. + def select_rows(sql, name = nil) + execute(sql, name).to_a + end + + # Executes the SQL statement in the context of this connection. + def execute(sql, name = nil) + # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been + # made since we established the connection + @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone + if name == :skip_logging + @connection.query(sql) + else + log(sql, name) { @connection.query(sql) } + end + rescue ActiveRecord::StatementInvalid => exception + if exception.message.split(":").first =~ /Packets out of order/ + raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings." + else + raise + end + end + + def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) + super + id_value || @connection.last_id + end + alias :create :insert_sql + + def update_sql(sql, name = nil) + super + @connection.affected_rows + end + + def begin_db_transaction + execute "BEGIN" + rescue Exception + # Transactions aren't supported + end + + def commit_db_transaction + execute "COMMIT" + rescue Exception + # Transactions aren't supported + end + + def rollback_db_transaction + execute "ROLLBACK" + rescue Exception + # Transactions aren't supported + end + + def create_savepoint + execute("SAVEPOINT #{current_savepoint_name}") + end + + def rollback_to_savepoint + execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}") + end + + def release_savepoint + execute("RELEASE SAVEPOINT #{current_savepoint_name}") + end + + def add_limit_offset!(sql, options) + limit, offset = options[:limit], options[:offset] + if limit && offset + sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}" + elsif limit + sql << " LIMIT #{sanitize_limit(limit)}" + elsif offset + sql << " OFFSET #{offset.to_i}" + end + sql + end + + # SCHEMA STATEMENTS ======================================== + + def structure_dump + if supports_views? + sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'" + else + sql = "SHOW TABLES" + end + + select_all(sql).inject("") do |structure, table| + table.delete('Table_type') + structure += select_one("SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}")["Create Table"] + ";\n\n" + end + end + + def recreate_database(name, options = {}) + drop_database(name) + create_database(name, options) + end + + # Create a new MySQL database with optional :charset and :collation. + # Charset defaults to utf8. + # + # Example: + # create_database 'charset_test', :charset => 'latin1', :collation => 'latin1_bin' + # create_database 'matt_development' + # create_database 'matt_development', :charset => :big5 + def create_database(name, options = {}) + if options[:collation] + execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`" + else + execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`" + end + end + + def drop_database(name) #:nodoc: + execute "DROP DATABASE IF EXISTS `#{name}`" + end + + def current_database + select_value 'SELECT DATABASE() as db' + end + + # Returns the database character set. + def charset + show_variable 'character_set_database' + end + + # Returns the database collation strategy. + def collation + show_variable 'collation_database' + end + + def tables(name = nil) + tables = [] + execute("SHOW TABLES", name).each do |field| + tables << field.first + end + tables + end + + def drop_table(table_name, options = {}) + super(table_name, options) + end + + def indexes(table_name, name = nil) + indexes = [] + current_index = nil + result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name) + result.each(:symbolize_keys => true, :as => :hash) do |row| + if current_index != row[:Key_name] + next if row[:Key_name] == PRIMARY # skip the primary key + current_index = row[:Key_name] + indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, []) + end + + indexes.last.columns << row[:Column_name] + end + indexes + end + + def columns(table_name, name = nil) + sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}" + columns = [] + result = execute(sql, :skip_logging) + result.each(:symbolize_keys => true, :as => :hash) { |field| + columns << Mysql2Column.new(field[:Field], field[:Default], field[:Type], field[:Null] == "YES") + } + columns + end + + def create_table(table_name, options = {}) + super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB")) + end + + def rename_table(table_name, new_name) + execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" + end + + def add_column(table_name, column_name, type, options = {}) + add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" + add_column_options!(add_column_sql, options) + add_column_position!(add_column_sql, options) + execute(add_column_sql) + end + + def change_column_default(table_name, column_name, default) + column = column_for(table_name, column_name) + change_column table_name, column_name, column.sql_type, :default => default + end + + def change_column_null(table_name, column_name, null, default = nil) + column = column_for(table_name, column_name) + + unless null || default.nil? + execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") + end + + change_column table_name, column_name, column.sql_type, :null => null + end + + def change_column(table_name, column_name, type, options = {}) + column = column_for(table_name, column_name) + + unless options_include_default?(options) + options[:default] = column.default + end + + unless options.has_key?(:null) + options[:null] = column.null + end + + change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" + add_column_options!(change_column_sql, options) + add_column_position!(change_column_sql, options) + execute(change_column_sql) + end + + def rename_column(table_name, column_name, new_column_name) + options = {} + if column = columns(table_name).find { |c| c.name == column_name.to_s } + options[:default] = column.default + options[:null] = column.null + else + raise ActiveRecordError, "No such column: #{table_name}.#{column_name}" + end + current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"] + rename_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" + add_column_options!(rename_column_sql, options) + execute(rename_column_sql) + end + + # Maps logical Rails types to MySQL-specific data types. + def type_to_sql(type, limit = nil, precision = nil, scale = nil) + return super unless type.to_s == 'integer' + + case limit + when 1; 'tinyint' + when 2; 'smallint' + when 3; 'mediumint' + when nil, 4, 11; 'int(11)' # compatibility with MySQL default + when 5..8; 'bigint' + else raise(ActiveRecordError, "No integer type has byte size #{limit}") + end + end + + def add_column_position!(sql, options) + if options[:first] + sql << " FIRST" + elsif options[:after] + sql << " AFTER #{quote_column_name(options[:after])}" + end + end + + def show_variable(name) + variables = select_all("SHOW VARIABLES LIKE '#{name}'") + variables.first['Value'] unless variables.empty? + end + + def pk_and_sequence_for(table) + keys = [] + result = execute("describe #{quote_table_name(table)}") + result.each(:symbolize_keys => true, :as => :hash) do |row| + keys << row[:Field] if row[:Key] == "PRI" + end + keys.length == 1 ? [keys.first, nil] : nil + end + + # Returns just a table's primary key + def primary_key(table) + pk_and_sequence = pk_and_sequence_for(table) + pk_and_sequence && pk_and_sequence.first + end + + def case_sensitive_equality_operator + "= BINARY" + end + + def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) + where_sql + end + + protected + def quoted_columns_for_index(column_names, options = {}) + length = options[:length] if options.is_a?(Hash) + + quoted_column_names = case length + when Hash + column_names.map {|name| length[name] ? "#{quote_column_name(name)}(#{length[name]})" : quote_column_name(name) } + when Fixnum + column_names.map {|name| "#{quote_column_name(name)}(#{length})"} + else + column_names.map {|name| quote_column_name(name) } + end + end + + def translate_exception(exception, message) + return super unless exception.respond_to?(:error_number) + + case exception.error_number + when 1062 + RecordNotUnique.new(message, exception) + when 1452 + InvalidForeignKey.new(message, exception) + else + super + end + end + + private + def connect + @connection = Mysql2::Client.new(@config) + configure_connection + end + + def configure_connection + @connection.query_options.merge!(:as => :array) + encoding = @config[:encoding] + execute("SET NAMES '#{encoding}'", :skip_logging) if encoding + + # By default, MySQL 'where id is null' selects the last inserted id. + # Turn this off. http://dev.rubyonrails.org/ticket/6778 + execute("SET SQL_AUTO_IS_NULL=0", :skip_logging) + end + + # Returns an array of record hashes with the column names as keys and + # column values as values. + def select(sql, name = nil) + execute(sql, name).each(:as => :hash) + end + + def supports_views? + version[0] >= 5 + end + + def version + @version ||= @connection.info[:version].scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i } + end + + def column_for(table_name, column_name) + unless column = columns(table_name).find { |c| c.name == column_name.to_s } + raise "No such column: #{table_name}.#{column_name}" + end + column + end + end + end +end -- 1.7.1 From 3c404c56ebd04bb4323637893d45ebc8f90f3e91 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 01:30:37 +0200 Subject: [PATCH 071/805] AS guide: documents date/datetime/time arithmetic with durations --- .../source/active_support_core_extensions.textile | 63 +++++++++++++++++++- 1 files changed, 62 insertions(+), 1 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 9d9053d..15136b7 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3009,6 +3009,26 @@ Date.new(2010, 1, 31).change(:month => 2) # => ArgumentError: invalid date
+h5. Durations + +Durations can be added and substracted to dates: + + +d = Date.current +# => Mon, 09 Aug 2010 +d + 1.year +# => Tue, 09 Aug 2011 +d - 3.hours +# => Sun, 08 Aug 2010 21:00:00 UTC +00:00 + + +They translate to calls to +since+ or +advance+. For example here we get the correct jump in the calendar reform: + + +Date.new(1582, 10, 4) + 1.day +# => Fri, 15 Oct 1582 + + h5. Timestamps INFO: The following methods return a +Time+ object if possible, otherwise a +DateTime+. If set, they honor the user time zone. @@ -3195,7 +3215,25 @@ DateTime.current.change(:month => 2, :day => 30) # => ArgumentError: invalid date -h4(#datetime-conversions). Conversions +h5. Durations + +Durations can be added and substracted to datetimes: + + +now = DateTime.current +# => Mon, 09 Aug 2010 23:15:17 +0000 +now + 1.year +# => Tue, 09 Aug 2011 23:15:17 +0000 +now - 1.week +# => Mon, 02 Aug 2010 23:15:17 +0000 + + +They translate to calls to +since+ or +advance+. For example here we get the correct jump in the calendar reform: + + +DateTime.new(1582, 10, 4, 23) + 1.hour +# => Fri, 15 Oct 1582 00:00:00 +0000 + h3. Extensions to +Time+ @@ -3243,6 +3281,9 @@ They are analogous. Please refer to their documentation above and take into acco * +Time+ understands DST, so you get correct DST calculations as in +Time.zone_default +# => # + # In Barcelona, 2010/03/28 02:00 +0100 becomes 2010/03/28 03:00 +0200 due to DST. t = Time.local_time(2010, 3, 28, 1, 59, 59) # => Sun Mar 28 01:59:59 +0100 2010 @@ -3287,6 +3328,26 @@ Both +local_time+ and +utc_time+ accept up to seven positional arguments: year, If the time to be constructed lies beyond the range supported by +Time+ in the runtime platform, usecs are discarded and a +DateTime+ object is returned instead. +h5. Durations + +Durations can be added and substracted to time objects: + + +now = Time.current +# => Mon, 09 Aug 2010 23:20:05 UTC +00:00 +now + 1.year +# => Tue, 09 Aug 2011 23:21:11 UTC +00:00 +now - 1.week +# => Mon, 02 Aug 2010 23:21:11 UTC +00:00 + + +They translate to calls to +since+ or +advance+. For example here we get the correct jump in the calendar reform: + + +Time.utc_time(1582, 10, 3) + 5.days +# => Mon Oct 18 00:00:00 UTC 1582 + + h3. Extensions to +Process+ ... -- 1.7.1 From 8968eecb9331c81a00c0843df8f8bf2fc353f463 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 01:53:53 +0200 Subject: [PATCH 072/805] AS guide: documents Process.daemon --- .../source/active_support_core_extensions.textile | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 15136b7..0650ba4 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3350,7 +3350,9 @@ Time.utc_time(1582, 10, 3) + 5.days h3. Extensions to +Process+ -... +h4. +daemon+ + +Ruby 1.9 provides +Process.daemon+, and Active Support defines it for previous versions. It accepts the same two arguments, whether it should chdir to the root directory (default, true), and whether it should inherit the standard file descriptors from the parent (default, false). h3. Extensions to +File+ -- 1.7.1 From 68bed3a4ad0da2dbaef0989978f4fe269c6956dc Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 03:28:59 +0200 Subject: [PATCH 073/805] AS guide: documents Module#delegate --- .../source/active_support_core_extensions.textile | 82 ++++++++++++++++++++ 1 files changed, 82 insertions(+), 0 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 0650ba4..3516055 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -984,6 +984,88 @@ though an anonymous module is unreachable by definition. NOTE: Defined in +active_support/core_ext/module/anonymous.rb+. +h4. Delegation + +The +delegate+ macro declares that some instance method has to be forwarded to some object. + +Let's imagine that users in some application have login information in the +User+ model but name and other data in a separate +Profile+ model: + + +class User < ActiveRecord::Base + has_one :profile +end + + +With that configuration you get a user's name via his profile, +user.profile.name+, but you could write a shortcut so that client code can read it directly: + + +class User < ActiveRecord::Base + has_one :profile + + def name + profile.name + end +end + + +That is what +delegate+ does for you: + + +class User < ActiveRecord::Base + has_one :profile + + delegate :name, :to => :profile +end + + +When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to: + + +delegate :logger, :to => :Rails +delegate :table_name, :to => 'self.class' + + +WARNING: If the +:prefix+ option is +true+ this is less generic, see below. + +By default, if the delegation raises +NoMethodError+ and the target is +nil+ the exception is propagated. You can ask that +nil+ is returned instead with the +:allow_nil+ option: + + +class User < ActiveRecord::Base + has_one :profile + + delegate :name, :to => :profile, :allow_nil => true +end + + +With +:allow_nil+ the call +user.name+ returns +nil+ if the user has no profile instead of raising an exception. + +The option +:prefix+ adds a prefix to the name of the generated method. This may be handy for example to get a better name: + + +class Account < ActiveRecord::Base + has_one :address + + delegate :street, :to => :address, :prefix => true +end + + +The previous example generates +Account#address_street+ rather than +Account#street+. + +WARNING: Since in this case the name of the generated method is composed of the target object and target method names, the +:to+ option must be a method name. + +A custom prefix may also be configured: + + +class User < ActiveRecord::Base + has_one :attachment + + delegate :size, :to => :attachment, :prefix => :avatar + + +In the previous example the macro generates +User#avatar_size+ rather than +User#size+. + +NOTE: Defined in +active_support/core_ext/module/delegation.rb+ + h3. Extensions to +Class+ h4. Class Attributes -- 1.7.1 From aaa52c6d1f9cc8cce31a1409ca0d4d7ab0cb7f7b Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 03:46:21 +0200 Subject: [PATCH 074/805] AS guide: documents Module#(instance_)method_names --- .../source/active_support_core_extensions.textile | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 3516055..6f6b9bb 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1066,6 +1066,18 @@ In the previous example the macro generates +User#avatar_size+ rather than +User NOTE: Defined in +active_support/core_ext/module/delegation.rb+ +h4. Method Names + +The builtin methods +instance_methods+ and +methods+ return method names as strings or symbols depending on the Ruby version. Active Support defines +instance_method_names+ and +method_names+ to be equivalent to them, respectively, but always getting strings back. + +For example, +ActionView::Helpers::FormBuilder+ knows this array difference is going to work no matter the Ruby version: + + +self.field_helpers = (FormHelper.instance_method_names - ['form_for']) + + +NOTE: Defined in +active_support/core_ext/module/method_names.rb+ + h3. Extensions to +Class+ h4. Class Attributes -- 1.7.1 From ca3fc4b325e946bf9103347df0d150ea6d6554e2 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 03:59:26 +0200 Subject: [PATCH 075/805] AS guide: documents Module#redefine_method --- .../source/active_support_core_extensions.textile | 21 ++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 6f6b9bb..f4a80ab 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1078,6 +1078,27 @@ self.field_helpers = (FormHelper.instance_method_names - ['form_for']) NOTE: Defined in +active_support/core_ext/module/method_names.rb+ +h4. Redefining Methods + +There are cases where you need to define a method with +define_method+, but don't know whether a method with that name already exists. If it does, a warning is issued if they are enabled. No big deal, but not clean either. + +The method +redefine_method+ prevents such a potential warning, removing the existing method before if needed. Rails uses it in a few places, for instance when it generates an association's API: + + +redefine_method("#{reflection.name}=") do |new_value| + association = association_instance_get(reflection.name) + + if association.nil? || association.target != new_value + association = association_proxy_class.new(self, reflection) + end + + association.replace(new_value) + association_instance_set(reflection.name, new_value.nil? ? nil : association) +end + + +NOTE: Defined in +active_support/core_ext/module/remove_method.rb+ + h3. Extensions to +Class+ h4. Class Attributes -- 1.7.1 From 63ffec85b7aacef8ba00019ef0ad2ca51c6b714d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 04:09:52 +0200 Subject: [PATCH 076/805] adds the AS guide to the guides index --- .../source/active_support_core_extensions.textile | 1 + railties/guides/source/index.html.erb | 4 ++++ railties/guides/source/layout.html.erb | 1 + 3 files changed, 6 insertions(+), 0 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index f4a80ab..5ac4277 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3543,4 +3543,5 @@ h3. Changelog "Lighthouse ticket":https://rails.lighthouseapp.com/projects/16213/tickets/67 +* August 10, 2010: Starts to take shape, added to the index. * April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn diff --git a/railties/guides/source/index.html.erb b/railties/guides/source/index.html.erb index 254ee91..a0db87c 100644 --- a/railties/guides/source/index.html.erb +++ b/railties/guides/source/index.html.erb @@ -88,6 +88,10 @@ Ruby on Rails Guides
+<%= guide("Active Support Core Extensions", 'active_support_core_extensions.html') do %> +

This guide documents the Ruby core extensions defined in Active Support.

+<% end %> + <%= guide("Rails Internationalization API", 'i18n.html') do %>

This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.

<% end %> diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb index c475831..cc7d54c 100644 --- a/railties/guides/source/layout.html.erb +++ b/railties/guides/source/layout.html.erb @@ -62,6 +62,7 @@
Digging Deeper
+
Active Support Core Extensions
Rails Internationalization API
Action Mailer Basics
Testing Rails Applications
-- 1.7.1 From 5859f5eee150e0c867c0529e8712fc4823de8c6d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 11:52:29 +0200 Subject: [PATCH 077/805] AS guide: removes some duplication, and makes a second pass on method delegation --- .../source/active_support_core_extensions.textile | 165 +++----------------- 1 files changed, 21 insertions(+), 144 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 5ac4277..53d59d0 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -667,129 +667,6 @@ end NOTE: Defined in +active_support/core_ext/module/attribute_accessors.rb+. -h4. Method Delegation - -The class method +delegate+ offers an easy way to forward methods. - -For example, if +User+ has some details like the age factored out to +Profile+, it could be handy to still be able to access such attributes directly, user.age, instead of having to explicit the chain user.profile.age. - -That can be accomplished by hand: - - -class User - has_one :profile - - def age - profile.age - end -end - - -But with +delegate+ you can make that shorter and the intention even more obvious: - - -class User - has_one :profile - - delegate :age, to => :profile -end - - -The macro accepts more than one method: - - -class User - has_one :profile - - delegate :age, :avatar, :twitter_username, to => :profile -end - - -Methods can be delegated to objects returned by methods, as in the examples above, but also to instance variables, class variables, and constants. Just pass their names as symbols or strings, including the at signs in the last cases. - -For example, +ActionView::Base+ delegates +erb_trim_mode=+: - - -module ActionView - class Base - delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' - end -end - - -In fact, you can delegate to any expression passed as a string. It will be evaluated in the context of the receiver. Controllers for example delegate alerts and notices to the current flash: - - -delegate :alert, :notice, :to => "request.flash" - - -If the target is +nil+ calling any delegated method will raise an exception even if +nil+ responds to such method. You can override this behavior setting the option +:allow_nil+ to true, in which case the forwarded call will simply return +nil+. - -If the target is a method, the name of delegated methods can also be prefixed. If the +:prefix+ option is set to (exactly) the +true+ object, the value of the +:to+ option is prefixed: - - -class Invoice - belongs_to :customer - - # defines a method called customer_name - delegate :name, :to => :customer, :prefix => true -end - - -And a custom prefix can be set as well, in that case it does not matter wheter the target is a method or not: - - -class Account - belongs_to :user - - # defines a method called admin_email - delegate :email, :to => :user, :prefix => 'admin' -end - - -NOTE: Defined in +active_support/core_ext/module/delegation.rb+. - -h4. Method Removal - -h5. +remove_possible_method+ - -The method +remove_possible_method+ is like the standard +remove_method+, except it silently returns on failure: - - -class A; end - -A.class_eval do - remove_method(:nonexistent) # raises NameError - remove_possible_method(:nonexistent) # no problem, continue -end - - -This may come in handy if you need to define a method that may already exist, since redefining a method issues a warning "method redefined; discarding old redefined_method_name". - -h5. +redefine_method(method_name, &block)+ - -The method first removes method with given name (using +remove_possible_method+) and then defines new one. - - -class A; end - -A.class_eval do - redefine_method(:foobar) do |foo| - #do something here - end - - #Code above does the same as this: - - method_name = :foobar - remove_possible_method(method_name) - define_method(method_name) do |foo| - #do something here - end -end - - -NOTE: Defined in +active_support/core_ext/module/remove_method.rb+. - h4. Parents h5. +parent+ @@ -984,9 +861,9 @@ though an anonymous module is unreachable by definition. NOTE: Defined in +active_support/core_ext/module/anonymous.rb+. -h4. Delegation +h4. Method Delegation -The +delegate+ macro declares that some instance method has to be forwarded to some object. +The macro +delegate+ offers an easy way to forward methods. Let's imagine that users in some application have login information in the +User+ model but name and other data in a separate +Profile+ model: @@ -996,7 +873,7 @@ class User < ActiveRecord::Base end -With that configuration you get a user's name via his profile, +user.profile.name+, but you could write a shortcut so that client code can read it directly: +With that configuration you get a user's name via his profile, +user.profile.name+, but it could be handy to still be able to access such attribute directly: class User < ActiveRecord::Base @@ -1018,10 +895,21 @@ class User < ActiveRecord::Base end -When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to: +It is shorter, and the intention more obvious. + +The macro accepts several methods: + + +delegate :name, :age, :address, :twitter, :to => :profile + + +When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such a expression is evaluated in the context of the receiver: +# delegates to the Rails constant delegate :logger, :to => :Rails + +# delegates to the receiver's class delegate :table_name, :to => 'self.class' @@ -1030,39 +918,28 @@ WARNING: If the +:prefix+ option is +true+ this is less generic, see below. By default, if the delegation raises +NoMethodError+ and the target is +nil+ the exception is propagated. You can ask that +nil+ is returned instead with the +:allow_nil+ option: -class User < ActiveRecord::Base - has_one :profile - - delegate :name, :to => :profile, :allow_nil => true -end +delegate :name, :to => :profile, :allow_nil => true -With +:allow_nil+ the call +user.name+ returns +nil+ if the user has no profile instead of raising an exception. +With +:allow_nil+ the call +user.name+ returns +nil+ if the user has no profile. The option +:prefix+ adds a prefix to the name of the generated method. This may be handy for example to get a better name: -class Account < ActiveRecord::Base - has_one :address - - delegate :street, :to => :address, :prefix => true -end +delegate :street, :to => :address, :prefix => true -The previous example generates +Account#address_street+ rather than +Account#street+. +The previous example generates +address_street+ rather than +street+. WARNING: Since in this case the name of the generated method is composed of the target object and target method names, the +:to+ option must be a method name. A custom prefix may also be configured: -class User < ActiveRecord::Base - has_one :attachment - - delegate :size, :to => :attachment, :prefix => :avatar +delegate :size, :to => :attachment, :prefix => :avatar -In the previous example the macro generates +User#avatar_size+ rather than +User#size+. +In the previous example the macro generates +avatar_size+ rather than +size+. NOTE: Defined in +active_support/core_ext/module/delegation.rb+ -- 1.7.1 From b2eaac24c360a116f434b72cff1e26a418e66288 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 10 Aug 2010 15:34:54 +0200 Subject: [PATCH 078/805] fixes a typo reported by rymai --- .../lib/active_model/validations/validates.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb index 0674640..3260e6b 100644 --- a/activemodel/lib/active_model/validations/validates.rb +++ b/activemodel/lib/active_model/validations/validates.rb @@ -40,7 +40,7 @@ module ActiveModel # validates :email, :presence => true, :email => true # end # - # Validator classes my also exist within the class being validated + # Validator classes may also exist within the class being validated # allowing custom modules of validators to be included as needed e.g. # # class Film -- 1.7.1 From 6f88b82263013ed241737fecc56ca87e7705fdc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 10 Aug 2010 11:18:58 -0300 Subject: [PATCH 079/805] Revert "require_dependency should require using the normal mechanism if possible to avoid double-requires" This was causing double requires since 991cd59a225b90ab1ba3 was reverted. This reverts commit 8bf79739b4219eb1d6464e6eb4853e92e81d7621. --- activesupport/lib/active_support/dependencies.rb | 22 +++++++--------------- 1 files changed, 7 insertions(+), 15 deletions(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 1b93eac..2b80bd2 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -276,22 +276,14 @@ module ActiveSupport #:nodoc: end def depend_on(file_name, swallow_load_errors = false, message = "No such file to load -- %s.rb") - #path = search_for_file(file_name) - require_or_load(file_name) - rescue LoadError - begin - if path = search_for_file(file_name) - require_or_load(path) - else - raise - end - rescue LoadError => load_error - unless swallow_load_errors - if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] - raise LoadError.new(message % file_name).copy_blame!(load_error) - end - raise + path = search_for_file(file_name) + require_or_load(path || file_name) + rescue LoadError => load_error + unless swallow_load_errors + if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] + raise LoadError.new(message % file_name).copy_blame!(load_error) end + raise end end -- 1.7.1 From d9b77ddecde431d3190c7e08d73e26055a667597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Silva?= Date: Tue, 10 Aug 2010 18:21:51 +0100 Subject: [PATCH 080/805] added support for more printers --- .../lib/active_support/testing/performance.rb | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index a124c6e..f7ddf64 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -178,7 +178,7 @@ begin RubyProf.pause profile_options[:runs].to_i.times { run_test(@metric, :profile) } @data = RubyProf.stop - @total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time } + @total = @data.threads.values.sum(0) { |method_infos| method_infos.max.total_time } end def report @@ -207,10 +207,14 @@ begin def output_filename(printer_class) suffix = case printer_class.name.demodulize - when 'FlatPrinter'; 'flat.txt' - when 'GraphPrinter'; 'graph.txt' - when 'GraphHtmlPrinter'; 'graph.html' - when 'CallTreePrinter'; 'tree.txt' + when 'FlatPrinter'; 'flat.txt' + when 'FlatPrinterWithLineNumbers'; 'flat_line_numbers.txt' + when 'GraphPrinter'; 'graph.txt' + when 'GraphHtmlPrinter'; 'graph.html' + when 'GraphYamlPrinter'; 'graph.yml' + when 'CallTreePrinter'; 'tree.txt' + when 'CallStackPrinter'; 'stack.html' + when 'DotPrinter'; 'graph.dot' else printer_class.name.sub(/Printer$/, '').underscore end -- 1.7.1 From 43b8722f4b0bbd4690dccc080bc3c11fc736e5a6 Mon Sep 17 00:00:00 2001 From: Nick Sieger Date: Wed, 4 Aug 2010 20:25:42 -0500 Subject: [PATCH 081/805] Missed one spot for --skip-active-record, which means that new Gemfile isn't set up right Signed-off-by: Santiago Pastorino --- .../rails/generators/rails/app/templates/Gemfile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 1980684..3a8a63a 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -13,7 +13,7 @@ gem 'rails', '<%= Rails::VERSION::STRING %>' # gem 'rails', :git => 'git://github.com/rails/rails.git' <%- end -%> -<% unless options[:skip_activerecord] -%> +<% unless options[:skip_active_record] -%> gem '<%= gem_for_database %>'<% if require_for_database %>, :require => '<%= require_for_database %>'<% end %> <% end -%> -- 1.7.1 From 1fbcd5f5fca165135ff773e94cdad00ee97b8aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20&=20Carlos=20Antonio=20da=20Silva?= Date: Wed, 11 Aug 2010 10:23:07 -0300 Subject: [PATCH 082/805] layout_for works again with objects as specified in the documentation and Rails 2.3 [#5357 state:resolved] --- actionpack/lib/action_view/render/layouts.rb | 12 ++++++++---- actionpack/test/fixtures/layouts/_customers.erb | 1 + .../test/fixtures/test/layout_render_object.erb | 1 + actionpack/test/template/render_test.rb | 5 +++++ 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 actionpack/test/fixtures/layouts/_customers.erb create mode 100644 actionpack/test/fixtures/test/layout_render_object.erb diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index a474783..8882acc 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -47,11 +47,15 @@ module ActionView # Hello David # # - def _layout_for(name = nil, &block) #:nodoc: - if !block || name - @_content_for[name || :layout].html_safe + def _layout_for(*args, &block) #:nodoc: + name = args.first + + if name.is_a?(Symbol) + @_content_for[name].html_safe + elsif block + capture(*args, &block) else - capture(&block) + @_content_for[:layout].html_safe end end diff --git a/actionpack/test/fixtures/layouts/_customers.erb b/actionpack/test/fixtures/layouts/_customers.erb new file mode 100644 index 0000000..ae63f13 --- /dev/null +++ b/actionpack/test/fixtures/layouts/_customers.erb @@ -0,0 +1 @@ +<%= yield Struct.new(:name).new("David") %> \ No newline at end of file diff --git a/actionpack/test/fixtures/test/layout_render_object.erb b/actionpack/test/fixtures/test/layout_render_object.erb new file mode 100644 index 0000000..acc4453 --- /dev/null +++ b/actionpack/test/fixtures/test/layout_render_object.erb @@ -0,0 +1 @@ +<%= render :layout => "layouts/customers" do |customer| %><%= customer.name %><% end %> \ No newline at end of file diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 059dced..60d4d9f 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -252,6 +252,11 @@ module RenderTestCases assert_equal %(\ntitle\n\n), @view.render(:file => "test/layout_render_file.erb") end + + def test_render_layout_with_object + assert_equal %(David), + @view.render(:file => "test/layout_render_object.erb") + end end class CachedViewRenderTest < ActiveSupport::TestCase -- 1.7.1 From e1b85c3bda78b887cb279b1c4092504feeacf6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 11 Aug 2010 10:26:07 -0300 Subject: [PATCH 083/805] Ensure @config is not a reserved instance variable in controllers. [#5342 state:resolved] --- activesupport/lib/active_support/configurable.rb | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb index f562e17..a0c9c9e 100644 --- a/activesupport/lib/active_support/configurable.rb +++ b/activesupport/lib/active_support/configurable.rb @@ -9,7 +9,7 @@ module ActiveSupport module ClassMethods def config - @config ||= ActiveSupport::InheritableOptions.new(superclass.respond_to?(:config) ? superclass.config : {}) + @_config ||= ActiveSupport::InheritableOptions.new(superclass.respond_to?(:config) ? superclass.config : {}) end def configure @@ -30,7 +30,7 @@ module ActiveSupport end def config - @config ||= ActiveSupport::InheritableOptions.new(self.class.config) + @_config ||= ActiveSupport::InheritableOptions.new(self.class.config) end end end \ No newline at end of file -- 1.7.1 From 8464ee065098ea7b6499775ef517ad1c4ba33029 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 11 Aug 2010 11:24:59 -0700 Subject: [PATCH 084/805] stop using private methods --- .../lib/active_record/relation/finder_methods.rb | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index b34c119..0c75acf 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -291,7 +291,7 @@ module ActiveRecord record = where(primary_key.eq(id)).first unless record - conditions = arel.send(:where_clauses).join(', ') + conditions = arel.wheres.map { |x| x.value }.join(', ') conditions = " [WHERE #{conditions}]" if conditions.present? raise RecordNotFound, "Couldn't find #{@klass.name} with ID=#{id}#{conditions}" end @@ -317,7 +317,7 @@ module ActiveRecord if result.size == expected_size result else - conditions = arel.send(:where_clauses).join(', ') + conditions = arel.wheres.map { |x| x.value }.join(', ') conditions = " [WHERE #{conditions}]" if conditions.present? error = "Couldn't find all #{@klass.name.pluralize} with IDs " -- 1.7.1 From dac2b37b037587053b53cb6ed3c67a1fd4339778 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 11 Aug 2010 11:28:13 -0700 Subject: [PATCH 085/805] unless Array#empty? is faster than if Array#present? --- .../lib/active_record/relation/query_methods.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index dfacde8..2a87668 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -217,7 +217,7 @@ module ActiveRecord end def build_select(arel, selects) - if selects.present? + unless selects.empty? @implicit_readonly = false # TODO: fix this ugly hack, we should refactor the callers to get an ARel compatible array. # Before this change we were passing to ARel the last element only, and ARel is capable of handling an array -- 1.7.1 From a56ee4c9a23ca4f41ea001810a7c2358cc043f1d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 11 Aug 2010 11:43:27 -0700 Subject: [PATCH 086/805] avoiding tap saves us time --- .../lib/active_record/relation/query_methods.rb | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 2a87668..6ed9602 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -49,7 +49,9 @@ module ActiveRecord def where(opts, *rest) value = build_where(opts, rest) - value ? clone.tap {|r| r.where_values += Array.wrap(value) } : clone + copy = clone + copy.where_values += Array.wrap(value) if value + copy end def having(*args) @@ -58,7 +60,9 @@ module ActiveRecord end def limit(value = true) - clone.tap {|r| r.limit_value = value } + copy = clone + copy.limit_value = value + copy end def offset(value = true) -- 1.7.1 From 5352a89d5027f87bd5794e003bf7a622e079bb8f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 11 Aug 2010 14:45:07 -0700 Subject: [PATCH 087/805] dry up the hash dup and avoid sending nil values --- .../associations/belongs_to_association.rb | 12 ++++++++---- .../associations/has_one_association.rb | 14 +++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 4558872..2eb56e5 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -49,12 +49,16 @@ module ActiveRecord else "find" end + + options = @reflection.options.dup + (options.keys - [:select, :include, :readonly]).each do |key| + options.delete key + end + options[:conditions] = conditions + the_target = @reflection.klass.send(find_method, @owner[@reflection.primary_key_name], - :select => @reflection.options[:select], - :conditions => conditions, - :include => @reflection.options[:include], - :readonly => @reflection.options[:readonly] + options ) if @owner[@reflection.primary_key_name] set_inverse_instance(the_target, @owner) the_target diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 68b8b79..a6e6bfa 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -79,13 +79,13 @@ module ActiveRecord private def find_target - the_target = @reflection.klass.find(:first, - :conditions => @finder_sql, - :select => @reflection.options[:select], - :order => @reflection.options[:order], - :include => @reflection.options[:include], - :readonly => @reflection.options[:readonly] - ) + options = @reflection.options.dup + (options.keys - [:select, :order, :include, :readonly]).each do |key| + options.delete key + end + options[:conditions] = @finder_sql + + the_target = @reflection.klass.find(:first, options) set_inverse_instance(the_target, @owner) the_target end -- 1.7.1 From ff760dd6ceee4414e54afdb346c322dee6280edc Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 11 Aug 2010 14:59:47 -0700 Subject: [PATCH 088/805] avoid multiple hash lookups --- .../lib/active_record/relation/spawn_methods.rb | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 7712ad2..02db8d2 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -80,10 +80,14 @@ module ActiveRecord options.assert_valid_keys(VALID_FIND_OPTIONS) - [:joins, :select, :group, :having, :limit, :offset, :from, :lock, :readonly].each do |finder| - relation = relation.send(finder, options[finder]) if options.has_key?(finder) + [:joins, :select, :group, :having, :limit, :offset, :from, :lock].each do |finder| + if value = options[finder] + relation = relation.send(finder, value) + end end + relation = relation.readonly(options[:readonly]) if options.key? :readonly + # Give precedence to newly-applied orders and groups to play nicely with with_scope [:group, :order].each do |finder| relation.send("#{finder}_values=", Array.wrap(options[finder]) + relation.send("#{finder}_values")) if options.has_key?(finder) -- 1.7.1 From bfd728182ce24c7d59e8dbeed705ed5e1361116c Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 11 Aug 2010 23:54:15 +0200 Subject: [PATCH 089/805] no need to assign if we are gonna return --- actionpack/lib/action_dispatch/http/cache.rb | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb index e9fdf75..047fab0 100644 --- a/actionpack/lib/action_dispatch/http/cache.rb +++ b/actionpack/lib/action_dispatch/http/cache.rb @@ -113,10 +113,10 @@ module ActionDispatch DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate" def set_conditional_cache_control! - control = @cache_control - return if self["Cache-Control"].present? + control = @cache_control + if control.empty? headers["Cache-Control"] = DEFAULT_CACHE_CONTROL elsif @cache_control[:no_cache] -- 1.7.1 From 36cb62eb9d88e5a826b03fafc61c34fbd7127b75 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 12 Aug 2010 00:15:29 +0200 Subject: [PATCH 090/805] AS guide: some revisions --- .../source/active_support_core_extensions.textile | 50 +++++++------------- 1 files changed, 17 insertions(+), 33 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 53d59d0..8b5f3ea 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1,8 +1,10 @@ h2. Active Support Core Extensions -Active Support is the Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff. It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Rails itself. +Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff. -By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Rails. +It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself. + +By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Active Support. endprologue. @@ -84,32 +86,25 @@ The following values are considered to be blank in a Rails application: WARNING: Note that numbers are not mentioned, in particular 0 and 0.0 are *not* blank. -For example, this method from +ActionDispatch::Response+ uses +blank?+ to easily be robust to +nil+ and whitespace strings in one shot: +For example, this method from +ActionDispatch::Session::AbstractStore+ uses +blank?+ for checking whether a session key is present: -def charset - charset = String(headers["Content-Type"] || headers["type"]).split(";")[1] - charset.blank? ? nil : charset.strip.split("=")[1] +def ensure_session_key! + if @key.blank? + raise ArgumentError, 'A key is required...' + end end -That's a typical use case for +blank?+. - -Here, the method Rails runs to instantiate observers upon initialization has nothing to do if there are none: +The method +present?+ is equivalent to +!blank?+. This example is taken from +ActionDispatch::Http::Cache::Response+: -def instantiate_observers - return if @observers.blank? - # ... +def set_conditional_cache_control! + return if self["Cache-Control"].present? + ... end -The method +present?+ is equivalent to +!blank?+: - - -assert @response.body.present? # same as !@response.body.blank? - - NOTE: Defined in +active_support/core_ext/object/blank.rb+. h4. +presence+ @@ -151,28 +146,17 @@ Active Support provides +duplicable?+ to programmatically query an object about false.duplicable? # => false -By definition all objects are +duplicable?+ except +nil+, +false+, +true+, symbols, numbers, and class objects. +By definition all objects are +duplicable?+ except +nil+, +false+, +true+, symbols, numbers, and class and module objects. -WARNING. Using +duplicable?+ is discouraged because it depends on a hard-coded list. Classes have means to disallow duplication like removing +dup+ and +clone+ or raising exceptions from them, only +rescue+ can tell. +WARNING. Any class can disallow duplication removing +dup+ and +clone+ or raising exceptions from them, only +rescue+ can tell whether a given arbitrary object is duplicable. +duplicable?+ depends on the hard-coded list above, but it is much faster than +rescue+. Use it only if you know the hard-coded list is enough in your use case. NOTE: Defined in +active_support/core_ext/object/duplicable.rb+. h4. +try+ -Sometimes you want to call a method provided the receiver object is not +nil+, which is something you usually check first. - -For instance, note how this method of +ActiveRecord::ConnectionAdapters::AbstractAdapter+ checks if there's a +@logger+: - - -def log_info(sql, name, ms) - if @logger && @logger.debug? - name = '%s (%.1fms)' % [name || 'SQL', ms] - @logger.debug(format_log_entry(name, sql.squeeze(' '))) - end -end - +Sometimes you want to call a method provided the receiver object is not +nil+, which is something you usually check first. +try+ is like +Object#send+ except that it returns +nil+ if sent to +nil+. -You can shorten that using +Object#try+. This method is a synonym for +Object#send+ except that it returns +nil+ if sent to +nil+. The previous example could then be rewritten as: +For instance, in this code from +ActiveRecord::ConnectionAdapters::AbstractAdapter+ +@logger+ could be +nil+, but you save the check and write in an optimistic style: def log_info(sql, name, ms) -- 1.7.1 From c8509d5303db0fd0930d09357b059bb4a6b19f9f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 11 Aug 2010 15:31:44 -0700 Subject: [PATCH 091/805] subtracting blank strings is slightly faster than blank? --- .../lib/active_record/relation/query_methods.rb | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 6ed9602..ac0b8d7 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -135,9 +135,7 @@ module ActiveRecord arel = build_joins(arel, @joins_values) unless @joins_values.empty? - @where_values.uniq.each do |where| - next if where.blank? - + (@where_values - ['']).uniq.each do |where| case where when Arel::SqlLiteral arel = arel.where(where) -- 1.7.1 From 1c970b83943acbb63ebad274a2881ae5f8515509 Mon Sep 17 00:00:00 2001 From: Paul Hieromnimon Date: Tue, 10 Aug 2010 19:09:24 -0700 Subject: [PATCH 092/805] Raising exception if fixture file can't be found --- activerecord/lib/active_record/fixtures.rb | 4 ++++ activerecord/test/cases/fixtures_test.rb | 11 +++++++++++ 2 files changed, 15 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index e44102b..4e49e9f 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -24,6 +24,8 @@ else end end +class FixturesFileNotFound < StandardError; end + # Fixtures are a way of organizing data that you want to test against; in short, sample data. # # = Fixture formats @@ -696,6 +698,8 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash) read_yaml_fixture_files elsif File.file?(csv_file_path) read_csv_fixture_files + else + raise FixturesFileNotFound, "Could not find #{yaml_file_path} or #{csv_file_path}" end end diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index 93f8749..a8c1c04 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -153,6 +153,17 @@ class FixturesTest < ActiveRecord::TestCase assert_not_nil Fixtures.new( Account.connection, "companies", 'Company', FIXTURES_ROOT + "/naked/yml/companies") end + def test_nonexistent_fixture_file + nonexistent_fixture_path = FIXTURES_ROOT + "/imnothere" + + #sanity check to make sure that this file never exists + assert Dir[nonexistent_fixture_path+"*"].empty? + + assert_raise(FixturesFileNotFound) do + Fixtures.new( Account.connection, "companies", 'Company', nonexistent_fixture_path) + end + end + def test_dirty_dirty_yaml_file assert_raise(Fixture::FormatError) do Fixtures.new( Account.connection, "courses", 'Course', FIXTURES_ROOT + "/naked/yml/courses") -- 1.7.1 From f2d22ecbb3c63a8197fa5a34d4488bc320952db1 Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 11 Aug 2010 18:37:06 -0700 Subject: [PATCH 093/805] =?UTF-8?q?Replace=20snowman=20with=20utf8=3D=E2=9C=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/action_view/helpers/form_tag_helper.rb | 2 +- actionpack/test/template/form_helper_test.rb | 2 +- actionpack/test/template/form_tag_helper_test.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 1ea8704..c1c5db0 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -538,7 +538,7 @@ module ActionView def extra_tags_for_form(html_options) snowman_tag = tag(:input, :type => "hidden", - :name => "_e", :value => "☃".html_safe) + :name => "utf8", :value => "✓".html_safe) method = html_options.delete("method").to_s diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index be66710..71a5ae0 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -1513,7 +1513,7 @@ class FormHelperTest < ActionView::TestCase def snowman(method = nil) txt = %{
} - txt << %{} + txt << %{} txt << %{} if method txt << %{
} end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 6c85952..532f086 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -12,7 +12,7 @@ class FormTagHelperTest < ActionView::TestCase method = options[:method] txt = %{
} - txt << %{} + txt << %{} txt << %{} if method txt << %{
} end -- 1.7.1 From 7325dd21b3d879955a4e8331bf44fd4b50572dc8 Mon Sep 17 00:00:00 2001 From: Mark Turner Date: Wed, 11 Aug 2010 23:17:01 -0700 Subject: [PATCH 094/805] fixed indentation in test cases Signed-off-by: wycats --- .../test/cases/adapters/mysql/connection_test.rb | 2 +- .../test/cases/associations/extension_test.rb | 3 +-- activerecord/test/cases/nested_attributes_test.rb | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb index 8e4842a..782aad7 100644 --- a/activerecord/test/cases/adapters/mysql/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql/connection_test.rb @@ -41,7 +41,7 @@ class MysqlConnectionTest < ActiveRecord::TestCase sleep 2 @connection.verify! assert @connection.active? - end + end # Test that MySQL allows multiple results for stored procedures if Mysql.const_defined?(:CLIENT_MULTI_RESULTS) diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb index 9390633..e9240de 100644 --- a/activerecord/test/cases/associations/extension_test.rb +++ b/activerecord/test/cases/associations/extension_test.rb @@ -52,8 +52,7 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase name = :association_name assert_equal 'DeveloperAssociationNameAssociationExtension', Developer.send(:create_extension_modules, name, extension, []).first.name - assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', -MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name + assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index df09bbd..dbe17a1 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -356,7 +356,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert_equal @ship.name, 'Nights Dirty Lightning' assert_equal @pirate, @ship.pirate - end + end def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @ship.reload.pirate_attributes = { 'id' => @pirate.id, 'catchphrase' => 'Arr' } -- 1.7.1 From 30ea923040ded944209c98383389b6c9aafe806a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 12 Aug 2010 12:04:16 -0300 Subject: [PATCH 095/805] Make update_attribute behave as in Rails 2.3 and document the behavior intrinsic to its implementation. --- activerecord/lib/active_record/persistence.rb | 63 ++++++++++++------------- activerecord/lib/active_record/timestamp.rb | 39 +++++++-------- activerecord/test/cases/dirty_test.rb | 7 ++- activerecord/test/cases/persistence_test.rb | 41 +++++++++------- 4 files changed, 77 insertions(+), 73 deletions(-) diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 71b46be..0188972 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -1,7 +1,7 @@ module ActiveRecord # = Active Record Persistence module Persistence - # Returns true if this object hasn't been saved yet -- that is, a record + # Returns true if this object hasn't been saved yet -- that is, a record # for the object doesn't exist in the data store yet; otherwise, returns false. def new_record? @new_record @@ -72,7 +72,7 @@ module ActiveRecord freeze end - # Deletes the record in the database and freezes this instance to reflect + # Deletes the record in the database and freezes this instance to reflect # that no changes should be made (since they can't be persisted). def destroy if persisted? @@ -83,15 +83,15 @@ module ActiveRecord freeze end - # Returns an instance of the specified +klass+ with the attributes of the - # current record. This is mostly useful in relation to single-table - # inheritance structures where you want a subclass to appear as the - # superclass. This can be used along with record identification in - # Action Pack to allow, say, Client < Company to do something + # Returns an instance of the specified +klass+ with the attributes of the + # current record. This is mostly useful in relation to single-table + # inheritance structures where you want a subclass to appear as the + # superclass. This can be used along with record identification in + # Action Pack to allow, say, Client < Company to do something # like render :partial => @client.becomes(Company) to render that # instance using the companies/company partial instead of clients/client. # - # Note: The new instance will share a link to the same attributes as the original class. + # Note: The new instance will share a link to the same attributes as the original class. # So any change to the attributes in either instance will affect the other. def becomes(klass) became = klass.new @@ -102,34 +102,19 @@ module ActiveRecord became end - # Updates a single attribute and saves the record. + # Updates a single attribute and saves the record. # This is especially useful for boolean flags on existing records. Also note that # - # * The attribute being updated must be a column name. # * Validation is skipped. - # * No callbacks are invoked. + # * Callbacks are invoked. # * updated_at/updated_on column is updated if that column is available. - # * Does not work on associations. - # * Does not work on attr_accessor attributes. - # * Does not work on new record. record.new_record? should return false for this method to work. - # * Updates only the attribute that is input to the method. If there are other changed attributes then - # those attributes are left alone. In that case even after this method has done its work record.changed? - # will return true. + # * Updates all the attributes that are dirty in this object. # def update_attribute(name, value) - raise ActiveRecordError, "#{name.to_s} is marked as readonly" if self.class.readonly_attributes.include? name.to_s - - changes = record_update_timestamps || {} - - if name - name = name.to_s - send("#{name}=", value) - changes[name] = read_attribute(name) - end - - @changed_attributes.except!(*changes.keys) - primary_key = self.class.primary_key - self.class.update_all(changes, { primary_key => self[primary_key] }) == 1 + name = name.to_s + raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attributes.include?(name) + send("#{name}=", value) + save(:validate => false) end # Updates the attributes of the model from the passed-in hash and saves the @@ -220,15 +205,27 @@ module ActiveRecord # Saves the record with the updated_at/on attributes set to the current time. # Please note that no validation is performed and no callbacks are executed. - # If an attribute name is passed, that attribute is updated along with + # If an attribute name is passed, that attribute is updated along with # updated_at/on attributes. # # Examples: # # product.touch # updates updated_at/on # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on - def touch(attribute = nil) - update_attribute(attribute, current_time_from_proper_timezone) + def touch(name = nil) + attributes = timestamp_attributes_for_update_in_model + attributes << name if name + + current_time = current_time_from_proper_timezone + changes = {} + + attributes.each do |column| + changes[column.to_s] = write_attribute(column.to_s, current_time) + end + + @changed_attributes.except!(*changes.keys) + primary_key = self.class.primary_key + self.class.update_all(changes, { primary_key => self[primary_key] }) == 1 end private diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index 5531d12..c6ff4b3 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -1,8 +1,8 @@ module ActiveRecord # = Active Record Timestamp - # + # # Active Record automatically timestamps create and update operations if the - # table has fields named created_at/created_on or + # table has fields named created_at/created_on or # updated_at/updated_on. # # Timestamping can be turned off by setting: @@ -21,7 +21,7 @@ module ActiveRecord # # This feature can easily be turned off by assigning value false . # - # If your attributes are time zone aware and you desire to skip time zone conversion for certain + # If your attributes are time zone aware and you desire to skip time zone conversion for certain # attributes then you can do following: # # Topic.skip_time_zone_conversion_for_attributes = [:written_on] @@ -39,34 +39,33 @@ module ActiveRecord if record_timestamps current_time = current_time_from_proper_timezone - timestamp_attributes_for_create.each do |column| + all_timestamp_attributes.each do |column| write_attribute(column.to_s, current_time) if respond_to?(column) && self.send(column).nil? end - - timestamp_attributes_for_update_in_model.each do |column| - write_attribute(column.to_s, current_time) if self.send(column).nil? - end end super end def update(*args) #:nodoc: - record_update_timestamps if !partial_updates? || changed? + if should_record_timestamps? + current_time = current_time_from_proper_timezone + + timestamp_attributes_for_update_in_model.each do |column| + column = column.to_s + next if attribute_changed?(column) + write_attribute(column, current_time) + end + end super end - def record_update_timestamps #:nodoc: - return unless record_timestamps - current_time = current_time_from_proper_timezone - timestamp_attributes_for_update_in_model.inject({}) do |hash, column| - hash[column.to_s] = write_attribute(column.to_s, current_time) - hash - end + def should_record_timestamps? + record_timestamps && !partial_updates? || changed? end - def timestamp_attributes_for_update_in_model #:nodoc: - timestamp_attributes_for_update.select { |elem| respond_to?(elem) } + def timestamp_attributes_for_update_in_model + timestamp_attributes_for_update.select { |c| respond_to?(c) } end def timestamp_attributes_for_update #:nodoc: @@ -78,9 +77,9 @@ module ActiveRecord end def all_timestamp_attributes #:nodoc: - timestamp_attributes_for_update + timestamp_attributes_for_create + timestamp_attributes_for_create + timestamp_attributes_for_update end - + def current_time_from_proper_timezone #:nodoc: self.class.default_timezone == :utc ? Time.now.utc : Time.now end diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index 837386e..75f7453 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -475,9 +475,10 @@ class DirtyTest < ActiveRecord::TestCase pirate = Pirate.find_by_catchphrase("Ahoy!") pirate.update_attribute(:catchphrase, "Ninjas suck!") - assert_equal 0, pirate.previous_changes.size - assert_nil pirate.previous_changes['catchphrase'] - assert_nil pirate.previous_changes['updated_on'] + assert_equal 2, pirate.previous_changes.size + assert_equal ["Ahoy!", "Ninjas suck!"], pirate.previous_changes['catchphrase'] + assert_not_nil pirate.previous_changes['updated_on'][0] + assert_not_nil pirate.previous_changes['updated_on'][1] assert !pirate.previous_changes.key?('parrot_id') assert !pirate.previous_changes.key?('created_on') end diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index d7666b1..c90c787 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -1,5 +1,6 @@ require "cases/helper" require 'models/post' +require 'models/comment' require 'models/author' require 'models/topic' require 'models/reply' @@ -332,23 +333,26 @@ class PersistencesTest < ActiveRecord::TestCase assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, 'black') } end - def test_update_attribute_with_one_changed_and_one_updated - t = Topic.order('id').limit(1).first - title, author_name = t.title, t.author_name - t.author_name = 'John' - t.update_attribute(:title, 'super_title') - assert_equal 'John', t.author_name - assert_equal 'super_title', t.title - assert t.changed?, "topic should have changed" - assert t.author_name_changed?, "author_name should have changed" - assert !t.title_changed?, "title should not have changed" - assert_nil t.title_change, 'title change should be nil' - assert_equal ['author_name'], t.changed - - t.reload - assert_equal 'David', t.author_name - assert_equal 'super_title', t.title - end + # This test is correct, but it is hard to fix it since + # update_attribute trigger simply call save! that triggers + # all callbacks. + # def test_update_attribute_with_one_changed_and_one_updated + # t = Topic.order('id').limit(1).first + # title, author_name = t.title, t.author_name + # t.author_name = 'John' + # t.update_attribute(:title, 'super_title') + # assert_equal 'John', t.author_name + # assert_equal 'super_title', t.title + # assert t.changed?, "topic should have changed" + # assert t.author_name_changed?, "author_name should have changed" + # assert !t.title_changed?, "title should not have changed" + # assert_nil t.title_change, 'title change should be nil' + # assert_equal ['author_name'], t.changed + # + # t.reload + # assert_equal 'David', t.author_name + # assert_equal 'super_title', t.title + # end def test_update_attribute_with_one_updated t = Topic.first @@ -366,10 +370,13 @@ class PersistencesTest < ActiveRecord::TestCase def test_update_attribute_for_udpated_at_on developer = Developer.find(1) prev_month = Time.now.prev_month + developer.update_attribute(:updated_at, prev_month) assert_equal prev_month, developer.updated_at + developer.update_attribute(:salary, 80001) assert_not_equal prev_month, developer.updated_at + developer.reload assert_not_equal prev_month, developer.updated_at end -- 1.7.1 From 06af2913466acb88d46fc18b60c13f5c071395b1 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Mon, 9 Aug 2010 13:37:36 -0400 Subject: [PATCH 096/805] adding more documentation for autosave option --- activerecord/lib/active_record/associations.rb | 3 +- .../lib/active_record/autosave_association.rb | 50 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 2556d24..1c683be 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -311,7 +311,8 @@ module ActiveRecord # You can set the :autosave option on a has_one, belongs_to, # has_many, or has_and_belongs_to_many association. Setting it # to +true+ will _always_ save the members, whereas setting it to +false+ will - # _never_ save the members. + # _never_ save the members. More details about :autosave option is available at + # autosave_association.rb . # # === One-to-one associations # diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 2c7afe3..c661d68 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -18,6 +18,10 @@ module ActiveRecord # Note that it also means that associations marked for destruction won't # be destroyed directly. They will however still be marked for destruction. # + # Do note that :autosave => false is not same as not declaring :autosave + # option. When :autosave option is not declared then it works in + # theoreticall :new_only mode. Look at has_many example discused below for details. + # # === One-to-one Example # # class Post @@ -57,27 +61,45 @@ module ActiveRecord # # === One-to-many Example # + # When autosave is not declared then also children will get saved when parent is saved + # in certain conditions. + # # Consider a Post model with many Comments: # # class Post - # has_many :comments, :autosave => true + # has_many :comments # :autosave option is no declared # end # - # Saving changes to the parent and its associated model can now be performed - # automatically _and_ atomically: + # post = Post.new(:title => 'ruby rocks') + # post.comments.build(:body => 'hello world') + # post.save #=> will save both post and comment # - # post = Post.find(1) - # post.title # => "The current global position of migrating ducks" - # post.comments.first.body # => "Wow, awesome info thanks!" - # post.comments.last.body # => "Actually, your article should be named differently." + # post = Post.create(:title => 'ruby rocks') + # post.comments.build(:body => 'hello world') + # post.save #=> will save both post and comment # - # post.title = "On the migration of ducks" - # post.comments.last.body = "Actually, your article should be named differently. [UPDATED]: You are right, thanks." + # post = Post.create(:title => 'ruby rocks') + # post.comments.create(:body => 'hello world') + # post.save #=> will save both post and comment # - # post.save - # post.reload - # post.title # => "On the migration of ducks" - # post.comments.last.body # => "Actually, your article should be named differently. [UPDATED]: You are right, thanks." + # post = Post.create(:title => 'ruby rocks') + # post.comments.build(:body => 'hello world') + # post.comments[0].body = 'hi everyone' + # post.save #=> will save both post and comment and comment will have 'hi everyone' + # + # In the above cases even without autosave option children got updated. + # + # class Post + # has_many :comments, :autosave => true + # end + # + # :autosave declaration is required if an attempt is made to change an existing + # associatin in memory. + # + # post = Post.create(:title => 'ruby rocks') + # post.comments.create(:body => 'hello world') + # post.comments[0].body = 'hi everyone' + # post.save #=> will save both post and comment and comment will have 'hi everyone' # # Destroying one of the associated models members, as part of the parent's # save action, is as simple as marking it for destruction: @@ -125,6 +147,8 @@ module ActiveRecord # post = Post.find(1) # post.author.name = '' # post.save(:validate => false) # => true + # + # Note that validation will be perfomend even if autosave option is not declared. module AutosaveAssociation extend ActiveSupport::Concern -- 1.7.1 From 198bffe3be42d54932e8458b4d8fd2cbb2a5eb09 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Thu, 12 Aug 2010 10:23:20 -0400 Subject: [PATCH 097/805] updating documentation for named_scope and default_scope --- activerecord/lib/active_record/base.rb | 10 ++++++++++ activerecord/lib/active_record/named_scope.rb | 9 +++++++++ 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8da4fbc..a464b65 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1147,6 +1147,16 @@ MSG # class Person < ActiveRecord::Base # default_scope order('last_name, first_name') # end + # + # default_scope is also applied while creating/building a record. It is not + # applied while updating a record. + # + # class Article < ActiveRecord::Base + # default_scope where(:published => true) + # end + # + # Article.new.published #=> true + # Article.create.published #=> true def default_scope(options = {}) self.default_scoping << construct_finder_arel(options, default_scoping.pop) end diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 0e56041..c950601 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -88,6 +88,15 @@ module ActiveRecord # end # end # end + # + # Scopes can also be used while creating/building a record. + # + # class Article < ActiveRecord::Base + # scope :published, where(:published => true) + # end + # + # Article.published.new.published #=> true + # Article.published.create.published #=> true def scope(name, scope_options = {}, &block) name = name.to_sym valid_scope_name?(name) -- 1.7.1 From 1e6e868d8c09c799440f14a5943c7a711131eec8 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 12 Aug 2010 16:41:34 +0200 Subject: [PATCH 098/805] commit review: applies guidelines to "# =>" --- activerecord/lib/active_record/base.rb | 4 ++-- activerecord/lib/active_record/named_scope.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index a464b65..4b550eb 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1155,8 +1155,8 @@ MSG # default_scope where(:published => true) # end # - # Article.new.published #=> true - # Article.create.published #=> true + # Article.new.published # => true + # Article.create.published # => true def default_scope(options = {}) self.default_scoping << construct_finder_arel(options, default_scoping.pop) end diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index c950601..bffc450 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -95,8 +95,8 @@ module ActiveRecord # scope :published, where(:published => true) # end # - # Article.published.new.published #=> true - # Article.published.create.published #=> true + # Article.published.new.published # => true + # Article.published.create.published # => true def scope(name, scope_options = {}, &block) name = name.to_sym valid_scope_name?(name) -- 1.7.1 From ab68d4b52e1d207196fb22e8a1eef32d0aeff6f6 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Thu, 12 Aug 2010 17:09:58 +0200 Subject: [PATCH 099/805] applied guidelines to "# =>" --- actionmailer/README.rdoc | 4 +- activemodel/README.rdoc | 14 ++++---- activerecord/CHANGELOG | 2 +- .../lib/active_record/autosave_association.rb | 10 +++--- activerecord/lib/active_record/reflection.rb | 2 +- activeresource/README.rdoc | 34 ++++++++++---------- activesupport/CHANGELOG | 6 ++-- .../lib/active_support/core_ext/class/attribute.rb | 12 +++--- .../core_ext/class/attribute_accessors.rb | 4 +- .../core_ext/class/inheritable_attributes.rb | 4 +- railties/guides/source/security.textile | 10 +++--- 11 files changed, 51 insertions(+), 51 deletions(-) diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc index b52c993..602326e 100644 --- a/actionmailer/README.rdoc +++ b/actionmailer/README.rdoc @@ -65,8 +65,8 @@ simply call the method and optionally call +deliver+ on the return value. Calling the method returns a Mail Message object: - message = Notifier.welcome #=> Returns a Mail::Message object - message.deliver #=> delivers the email + message = Notifier.welcome # => Returns a Mail::Message object + message.deliver # => delivers the email Or you can just chain the methods together like: diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index 89cacbc..73c58a8 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -107,8 +107,8 @@ modules: extend ActiveModel::Naming end - NamedPerson.model_name #=> "NamedPerson" - NamedPerson.model_name.human #=> "Named person" + NamedPerson.model_name # => "NamedPerson" + NamedPerson.model_name.human # => "Named person" {Learn more}[link:classes/ActiveModel/Naming.html] @@ -139,7 +139,7 @@ modules: end Person.human_attribute_name('my_attribute') - #=> "My attribute" + # => "My attribute" {Learn more}[link:classes/ActiveModel/Translation.html] @@ -157,7 +157,7 @@ modules: person = Person.new person.first_name = 'zoolander' - person.valid? #=> false + person.valid? # => false {Learn more}[link:classes/ActiveModel/Validations.html] @@ -176,9 +176,9 @@ modules: end p = ValidatorPerson.new - p.valid? #=> false - p.errors.full_messages #=> ["Name must exist"] + p.valid? # => false + p.errors.full_messages # => ["Name must exist"] p.name = "Bob" - p.valid? #=> true + p.valid? # => true {Learn more}[link:classes/ActiveModel/Validator.html] diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 20b2286..972c907 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -966,7 +966,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Made increment_counter/decrement_counter play nicely with optimistic locking, and added a more general update_counters method [Jamis Buck] * Reworked David's query cache to be available as Model.cache {...}. For the duration of the block no select query should be run more then once. Any inserts/deletes/executes will flush the whole cache however [Tobias Lütke] - Task.cache { Task.find(1); Task.find(1) } #=> 1 query + Task.cache { Task.find(1); Task.find(1) } # => 1 query * When dealing with SQLite3, use the table_info pragma helper, so that the bindings can do some translation for when sqlite3 breaks incompatibly between point releases. [Jamis Buck] diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index c661d68..dc6352a 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -72,20 +72,20 @@ module ActiveRecord # # post = Post.new(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') - # post.save #=> will save both post and comment + # post.save # => will save both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') - # post.save #=> will save both post and comment + # post.save # => will save both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.create(:body => 'hello world') - # post.save #=> will save both post and comment + # post.save # => will save both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') # post.comments[0].body = 'hi everyone' - # post.save #=> will save both post and comment and comment will have 'hi everyone' + # post.save # => will save both post and comment and comment will have 'hi everyone' # # In the above cases even without autosave option children got updated. # @@ -99,7 +99,7 @@ module ActiveRecord # post = Post.create(:title => 'ruby rocks') # post.comments.create(:body => 'hello world') # post.comments[0].body = 'hi everyone' - # post.save #=> will save both post and comment and comment will have 'hi everyone' + # post.save # => will save both post and comment and comment will have 'hi everyone' # # Destroying one of the associated models members, as part of the parent's # save action, is as simple as marking it for destruction: diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 7f47a81..8295fd6 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -41,7 +41,7 @@ module ActiveRecord # Returns the AggregateReflection object for the named +aggregation+ (use the symbol). # - # Account.reflect_on_aggregation(:balance) #=> the balance AggregateReflection + # Account.reflect_on_aggregation(:balance) # => the balance AggregateReflection # def reflect_on_aggregation(aggregation) reflections[aggregation].is_a?(AggregateReflection) ? reflections[aggregation] : nil diff --git a/activeresource/README.rdoc b/activeresource/README.rdoc index 127ac5b..ad58eaf 100644 --- a/activeresource/README.rdoc +++ b/activeresource/README.rdoc @@ -34,7 +34,7 @@ lifecycle methods that operate against a persistent store. # Find a person with id = 1 ryan = Person.find(1) - Person.exists?(1) #=> true + Person.exists?(1) # => true As you can see, the methods are quite similar to Active Record's methods for dealing with database records. But rather than dealing directly with a database record, you're dealing with HTTP resources (which may or may not be database records). @@ -69,8 +69,8 @@ for a request for a single element, the XML of that item is expected in response The XML document that is received is used to build a new object of type Person, with each XML element becoming an attribute on the object. - ryan.is_a? Person #=> true - ryan.attribute1 #=> 'value1' + ryan.is_a? Person # => true + ryan.attribute1 # => 'value1' Any complex element (one that contains other elements) becomes its own object: @@ -81,8 +81,8 @@ Any complex element (one that contains other elements) becomes its own object: # for GET http://api.people.com:3000/people/1.xml # ryan = Person.find(1) - ryan.complex #=> - ryan.complex.attribute2 #=> 'value2' + ryan.complex # => + ryan.complex.attribute2 # => 'value2' Collections can also be requested in a similar fashion @@ -96,8 +96,8 @@ Collections can also be requested in a similar fashion # for GET http://api.people.com:3000/people.xml # people = Person.find(:all) - people.first #=> 'Ryan' ...> - people.last #=> 'Jim' ...> + people.first # => 'Ryan' ...> + people.last # => 'Jim' ...> ==== Create @@ -118,10 +118,10 @@ as the id of the ARes object. # Response (201): Location: http://api.people.com:3000/people/2 # ryan = Person.new(:first => 'Ryan') - ryan.new? #=> true - ryan.save #=> true - ryan.new? #=> false - ryan.id #=> 2 + ryan.new? # => true + ryan.save # => true + ryan.new? # => false + ryan.id # => 2 ==== Update @@ -139,9 +139,9 @@ server side was successful. # is expected with code (204) # ryan = Person.find(1) - ryan.first #=> 'Ryan' + ryan.first # => 'Ryan' ryan.first = 'Rizzle' - ryan.save #=> true + ryan.save # => true ==== Delete @@ -155,10 +155,10 @@ Destruction of a resource can be invoked as a class and instance method of the r # is expected with response code (200) # ryan = Person.find(1) - ryan.destroy #=> true - ryan.exists? #=> false - Person.delete(2) #=> true - Person.exists?(2) #=> false + ryan.destroy # => true + ryan.exists? # => false + Person.delete(2) # => true + Person.exists?(2) # => false You can find more usage information in the ActiveResource::Base documentation. diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 8485e7d..53e4d19 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -245,8 +245,8 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl * Add Array#in_groups which splits or iterates over the array in specified number of groups. #579. [Adrian Mugnolo] Example: a = (1..10).to_a - a.in_groups(3) #=> [[1, 2, 3, 4], [5, 6, 7, nil], [8, 9, 10, nil]] - a.in_groups(3, false) #=> [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] + a.in_groups(3) # => [[1, 2, 3, 4], [5, 6, 7, nil], [8, 9, 10, nil]] + a.in_groups(3, false) # => [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] * Fix TimeWithZone unmarshaling: coerce unmarshaled Time instances to utc, because Ruby's marshaling of Time instances doesn't respect the zone [Geoff Buesing] @@ -942,7 +942,7 @@ public for compatibility. [Jeremy Kemper] * Enhance Symbol#to_proc so it works with list objects, such as multi-dimensional arrays. Closes #5295 [nov@yo.rim.or.jp]. Example: {1 => "one", 2 => "two", 3 => "three"}.sort_by(&:first).map(&:last) - #=> ["one", "two", "three"] + # => ["one", "two", "three"] * Added Hash.create_from_xml(string) which will create a hash from a XML string and even typecast if possible [David Heinemeier Hansson]. Example: diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb index bfa57fe..79d5c40 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute.rb @@ -29,19 +29,19 @@ class Class # In such cases, you don't want to do changes in places but use setters: # # Base.setting = [] - # Base.setting #=> [] - # Subclass.setting #=> [] + # Base.setting # => [] + # Subclass.setting # => [] # # # Appending in child changes both parent and child because it is the same object: # Subclass.setting << :foo - # Base.setting #=> [:foo] - # Subclass.setting #=> [:foo] + # Base.setting # => [:foo] + # Subclass.setting # => [:foo] # # # Use setters to not propagate changes: # Base.setting = [] # Subclass.setting += [:foo] - # Base.setting #=> [] - # Subclass.setting #=> [:foo] + # Base.setting # => [] + # Subclass.setting # => [:foo] # # For convenience, a query method is defined as well: # diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb index 4e35b1b..a903735 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb @@ -12,8 +12,8 @@ require 'active_support/core_ext/array/extract_options' # end # # Person.hair_colors = [:brown, :black, :blonde, :red] -# Person.hair_colors #=> [:brown, :black, :blonde, :red] -# Person.new.hair_colors #=> [:brown, :black, :blonde, :red] +# Person.hair_colors # => [:brown, :black, :blonde, :red] +# Person.new.hair_colors # => [:brown, :black, :blonde, :red] # # To opt out of the instance writer method, pass :instance_writer => false. # To opt out of the instance reader method, pass :instance_reader => false. diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb index e844cf5..6891c66 100644 --- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -22,8 +22,8 @@ end # end # # Person.hair_colors = [:brown, :black, :blonde, :red] -# Person.hair_colors #=> [:brown, :black, :blonde, :red] -# Person.new.hair_colors #=> [:brown, :black, :blonde, :red] +# Person.hair_colors # => [:brown, :black, :blonde, :red] +# Person.new.hair_colors # => [:brown, :black, :blonde, :red] # # To opt out of the instance writer method, pass :instance_writer => false. # To opt out of the instance reader method, pass :instance_reader => false. diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 8ce0001..6372c60 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -371,7 +371,7 @@ The mass-assignment feature may become a problem, as it allows an attacker to se def signup - params[:user] #=> {:name => “ow3ned”, :admin => true} + params[:user] # => {:name => “ow3ned”, :admin => true} @user = User.new(params[:user]) end @@ -385,7 +385,7 @@ Mass-assignment saves you much work, because you don't have to set each value in This will set the following parameters in the controller: -params[:user] #=> {:name => “ow3ned”, :admin => true} +params[:user] # => {:name => “ow3ned”, :admin => true} So if you create a new user using mass-assignment, it may be too easy to become an administrator. @@ -423,11 +423,11 @@ attr_accessible :name If you want to set a protected attribute, you will to have to assign it individually: -params[:user] #=> {:name => "ow3ned", :admin => true} +params[:user] # => {:name => "ow3ned", :admin => true} @user = User.new(params[:user]) -@user.admin #=> false # not mass-assigned +@user.admin # => false # not mass-assigned @user.admin = true -@user.admin #=> true +@user.admin # => true A more paranoid technique to protect your whole project would be to enforce that all models whitelist their accessible attributes. This can be easily achieved with a very simple initializer: -- 1.7.1 From 4dcce5d06ef57aa0f179ac2c68c28d749606d068 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 12 Aug 2010 17:29:42 +0200 Subject: [PATCH 100/805] revises some autosave docs, style and content --- activerecord/lib/active_record/associations.rb | 3 +- .../lib/active_record/autosave_association.rb | 79 ++++++-------------- 2 files changed, 23 insertions(+), 59 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 1c683be..65f09e9 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -957,8 +957,7 @@ module ActiveRecord # If false, don't validate the associated objects when saving the parent object. true by default. # [:autosave] # If true, always save the associated objects or destroy them if marked for destruction, - # when saving the parent object. - # If false, never save or destroy the associated objects. + # when saving the parent object. If false, never save or destroy the associated objects. # By default, only save associated objects that are new records. # [:inverse_of] # Specifies the name of the belongs_to association on the associated object diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index dc6352a..1315914 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -3,13 +3,13 @@ require 'active_support/core_ext/array/wrap' module ActiveRecord # = Active Record Autosave Association # - # AutosaveAssociation is a module that takes care of automatically saving - # associacted records when parent is saved. In addition to saving, it + # +AutosaveAssociation+ is a module that takes care of automatically saving + # associacted records when their parent is saved. In addition to saving, it # also destroys any associated records that were marked for destruction. - # (See mark_for_destruction and marked_for_destruction?) + # (See +mark_for_destruction+ and marked_for_destruction?). # # Saving of the parent, its associations, and the destruction of marked - # associations, all happen inside 1 transaction. This should never leave the + # associations, all happen inside a transaction. This should never leave the # database in an inconsistent state. # # If validations for any of the associations fail, their error messages will @@ -18,9 +18,8 @@ module ActiveRecord # Note that it also means that associations marked for destruction won't # be destroyed directly. They will however still be marked for destruction. # - # Do note that :autosave => false is not same as not declaring :autosave - # option. When :autosave option is not declared then it works in - # theoreticall :new_only mode. Look at has_many example discused below for details. + # Note that :autosave => false is not same as not declaring :autosave. + # When the :autosave option is not present new associations are saved. # # === One-to-one Example # @@ -32,7 +31,7 @@ module ActiveRecord # automatically _and_ atomically: # # post = Post.find(1) - # post.title # => "The current global position of migrating ducks" + # post.title # => "The current global position of migrating ducks" # post.author.name # => "alloy" # # post.title = "On the migration of ducks" @@ -40,7 +39,7 @@ module ActiveRecord # # post.save # post.reload - # post.title # => "On the migration of ducks" + # post.title # => "On the migration of ducks" # post.author.name # => "Eloy Duran" # # Destroying an associated model, as part of the parent's save action, is as @@ -50,6 +49,7 @@ module ActiveRecord # post.author.marked_for_destruction? # => true # # Note that the model is _not_ yet removed from the database: + # # id = post.author.id # Author.find_by_id(id).nil? # => false # @@ -57,14 +57,12 @@ module ActiveRecord # post.reload.author # => nil # # Now it _is_ removed from the database: + # # Author.find_by_id(id).nil? # => true # # === One-to-many Example # - # When autosave is not declared then also children will get saved when parent is saved - # in certain conditions. - # - # Consider a Post model with many Comments: + # When :autosave is not declared new children are saved when their parent is saved: # # class Post # has_many :comments # :autosave option is no declared @@ -72,43 +70,36 @@ module ActiveRecord # # post = Post.new(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') - # post.save # => will save both post and comment + # post.save # => saves both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') - # post.save # => will save both post and comment + # post.save # => saves both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.create(:body => 'hello world') - # post.save # => will save both post and comment - # - # post = Post.create(:title => 'ruby rocks') - # post.comments.build(:body => 'hello world') - # post.comments[0].body = 'hi everyone' - # post.save # => will save both post and comment and comment will have 'hi everyone' + # post.save # => saves both post and comment # - # In the above cases even without autosave option children got updated. + # When :autosave is true all children is saved, no matter whether they are new records: # # class Post # has_many :comments, :autosave => true # end # - # :autosave declaration is required if an attempt is made to change an existing - # associatin in memory. - # # post = Post.create(:title => 'ruby rocks') # post.comments.create(:body => 'hello world') # post.comments[0].body = 'hi everyone' - # post.save # => will save both post and comment and comment will have 'hi everyone' + # post.save # => saves both post and comment, with 'hi everyone' as title # - # Destroying one of the associated models members, as part of the parent's - # save action, is as simple as marking it for destruction: + # Destroying one of the associated models as part of the parent's save action + # is as simple as marking it for destruction: # # post.comments.last.mark_for_destruction # post.comments.last.marked_for_destruction? # => true # post.comments.length # => 2 # # Note that the model is _not_ yet removed from the database: + # # id = post.comments.last.id # Comment.find_by_id(id).nil? # => false # @@ -116,39 +107,13 @@ module ActiveRecord # post.reload.comments.length # => 1 # # Now it _is_ removed from the database: + # # Comment.find_by_id(id).nil? # => true # # === Validation # - # Validation is performed on the parent as usual, but also on all autosave - # enabled associations. If any of the associations fail validation, its - # error messages will be applied on the parents errors object and validation - # of the parent will fail. - # - # Consider a Post model with Author which validates the presence of its name - # attribute: - # - # class Post - # has_one :author, :autosave => true - # end - # - # class Author - # validates_presence_of :name - # end - # - # post = Post.find(1) - # post.author.name = '' - # post.save # => false - # post.errors # => #["can't be blank"]}, @base=#> - # - # No validations will be performed on the associated models when validations - # are skipped for the parent: - # - # post = Post.find(1) - # post.author.name = '' - # post.save(:validate => false) # => true - # - # Note that validation will be perfomend even if autosave option is not declared. + # Validations on children records are run or not depending on the :validate + # option of the association. module AutosaveAssociation extend ActiveSupport::Concern -- 1.7.1 From 9528aa9f865cb22f3fec21dbaa9f3a434292af4e Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 3 Aug 2010 17:26:59 -0400 Subject: [PATCH 101/805] Ensure we can nest include calls [#5285 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../lib/active_record/relation/query_methods.rb | 2 +- .../lib/active_record/relation/spawn_methods.rb | 8 +++++++- activerecord/test/cases/relations_test.rb | 12 +++++++++++- activerecord/test/models/author.rb | 3 +++ activerecord/test/models/car.rb | 5 +++++ activerecord/test/models/tyre.rb | 3 +++ activerecord/test/schema/schema.rb | 4 ++++ 7 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 activerecord/test/models/tyre.rb diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index ac0b8d7..e8ae6a1 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -11,7 +11,7 @@ module ActiveRecord def includes(*args) args.reject! { |a| a.blank? } - clone.tap {|r| r.includes_values += args if args.present? } + clone.tap {|r| r.includes_values = (r.includes_values + args).flatten.uniq if args.present? } end def eager_load(*args) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 02db8d2..f857e50 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -8,7 +8,13 @@ module ActiveRecord ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - [:joins, :where]).each do |method| value = r.send(:"#{method}_values") - merged_relation.send(:"#{method}_values=", value) if value.present? + if value.present? + if method == :includes + merged_relation = merged_relation.includes(value) + else + merged_relation.send(:"#{method}_values=", value) + end + end end merged_relation = merged_relation.joins(r.joins_values) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index ac7b501..bcc36d7 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -10,10 +10,20 @@ require 'models/entrant' require 'models/developer' require 'models/company' require 'models/bird' +require 'models/car' +require 'models/engine' +require 'models/tyre' + class RelationTest < ActiveRecord::TestCase fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments, - :taggings + :taggings, :cars + + def test_two_named_scopes_with_includes_should_not_drop_any_include + car = Car.incl_engines.incl_tyres.first + assert_no_queries { car.tyres.length } + assert_no_queries { car.engines.length } + end def test_apply_relation_as_where_id posts = Post.arel_table diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 7279784..34bfd2d 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -93,6 +93,9 @@ class Author < ActiveRecord::Base belongs_to :author_address, :dependent => :destroy belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress" + scope :relation_include_posts, includes(:posts) + scope :relation_include_tags, includes(:tags) + attr_accessor :post_log after_initialize :set_post_log diff --git a/activerecord/test/models/car.rb b/activerecord/test/models/car.rb index 1101180..faf4e6c 100644 --- a/activerecord/test/models/car.rb +++ b/activerecord/test/models/car.rb @@ -1,4 +1,9 @@ class Car < ActiveRecord::Base + has_many :tyres has_many :engines has_many :wheels, :as => :wheelable + + scope :incl_tyres, includes(:tyres) + scope :incl_engines, includes(:engines) + end diff --git a/activerecord/test/models/tyre.rb b/activerecord/test/models/tyre.rb new file mode 100644 index 0000000..bc3444a --- /dev/null +++ b/activerecord/test/models/tyre.rb @@ -0,0 +1,3 @@ +class Tyre < ActiveRecord::Base + belongs_to :car +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index fc3810f..c72f7b2 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -194,6 +194,10 @@ ActiveRecord::Schema.define do t.integer :car_id end + create_table :tyres, :force => true do |t| + t.integer :car_id + end + create_table :entrants, :force => true do |t| t.string :name, :null => false t.integer :course_id, :null => false -- 1.7.1 From d03a1249a096bac6b5913dcfd66ab29795f21b28 Mon Sep 17 00:00:00 2001 From: Greg Campbell Date: Thu, 5 Aug 2010 12:09:57 -0700 Subject: [PATCH 102/805] Add missing ActiveModel::Validations require MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#5311 state: resolved] ActiveModel::Validations uses Hash#except, but does not require it from ActiveSupport. (This wasn't showing up in the tests, because it was required in the helper, and was also required in ActiveModel::Serialization). Signed-off-by: José Valim --- activemodel/lib/active_model/validations.rb | 1 + activemodel/test/cases/helper.rb | 1 - 2 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 2927654..9e4149f 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -2,6 +2,7 @@ require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/except' require 'active_model/errors' require 'active_model/validations/callbacks' diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb index a32f114..a81584b 100644 --- a/activemodel/test/cases/helper.rb +++ b/activemodel/test/cases/helper.rb @@ -6,7 +6,6 @@ $:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) require 'config' require 'active_model' require 'active_support/core_ext/string/access' -require 'active_support/core_ext/hash/except' # Show backtraces for deprecated behavior for quicker cleanup. ActiveSupport::Deprecation.debug = true -- 1.7.1 From 9df227983f08a2f46725f5909ab3b85e7b206c98 Mon Sep 17 00:00:00 2001 From: Subba Rao Pasupuleti Date: Wed, 4 Aug 2010 11:04:41 -0400 Subject: [PATCH 103/805] tidy up validations length code [#5297 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- activemodel/lib/active_model/validations/length.rb | 8 ++------ 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index a7af4f2..ecae73a 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -41,13 +41,9 @@ module ActiveModel CHECKS.each do |key, validity_check| next unless check_value = options[key] - valid_value = if key == :maximum - value.nil? || value.size.send(validity_check, check_value) - else - value && value.size.send(validity_check, check_value) - end + value ||= [] if key == :maximum - next if valid_value + next if value && value.size.send(validity_check, check_value) errors_options = options.except(*RESERVED_OPTIONS) errors_options[:count] = check_value -- 1.7.1 From fe2d65864e6a89bfa9936ca7035b16e43cd3c394 Mon Sep 17 00:00:00 2001 From: Subba Rao Pasupuleti Date: Tue, 3 Aug 2010 17:04:41 -0400 Subject: [PATCH 104/805] no callbacks should be created for empty array [#5289 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- activemodel/lib/active_model/callbacks.rb | 9 ++++++--- activemodel/test/cases/callbacks_test.rb | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/activemodel/lib/active_model/callbacks.rb b/activemodel/lib/active_model/callbacks.rb index 8c10c54..b150fc6 100644 --- a/activemodel/lib/active_model/callbacks.rb +++ b/activemodel/lib/active_model/callbacks.rb @@ -90,10 +90,13 @@ module ActiveModel # def define_model_callbacks(*callbacks) options = callbacks.extract_options! - options = { :terminator => "result == false", :scope => [:kind, :name] }.merge(options) + options = { + :terminator => "result == false", + :scope => [:kind, :name], + :only => [:before, :around, :after] + }.merge(options) - types = Array.wrap(options.delete(:only)) - types = [:before, :around, :after] if types.empty? + types = Array.wrap(options.delete(:only)) callbacks.each do |callback| define_callbacks(callback, options) diff --git a/activemodel/test/cases/callbacks_test.rb b/activemodel/test/cases/callbacks_test.rb index 9675b5d..64dc7b5 100644 --- a/activemodel/test/cases/callbacks_test.rb +++ b/activemodel/test/cases/callbacks_test.rb @@ -16,6 +16,8 @@ class CallbacksTest < ActiveModel::TestCase define_model_callbacks :create define_model_callbacks :initialize, :only => :after + define_model_callbacks :multiple, :only => [:before, :around] + define_model_callbacks :empty, :only => [] before_create :before_create around_create CallbackValidator.new @@ -67,4 +69,16 @@ class CallbacksTest < ActiveModel::TestCase assert !ModelCallbacks.respond_to?(:around_initialize) assert_respond_to ModelCallbacks, :after_initialize end + + test "only selects which types of callbacks should be created from an array list" do + assert_respond_to ModelCallbacks, :before_multiple + assert_respond_to ModelCallbacks, :around_multiple + assert !ModelCallbacks.respond_to?(:after_multiple) + end + + test "no callbacks should be created" do + assert !ModelCallbacks.respond_to?(:before_empty) + assert !ModelCallbacks.respond_to?(:around_empty) + assert !ModelCallbacks.respond_to?(:after_empty) + end end -- 1.7.1 From 91ae6e99333059f79aae4bca6a6caacfcc7732b3 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 12 Aug 2010 19:30:51 +0200 Subject: [PATCH 105/805] be more precise re :validate and :autosave --- activerecord/lib/active_record/associations.rb | 8 ++++---- .../lib/active_record/autosave_association.rb | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 65f09e9..c6aefdc 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -954,7 +954,7 @@ module ActiveRecord # [:readonly] # If true, all the associated objects are readonly through the association. # [:validate] - # If false, don't validate the associated objects when saving the parent object. true by default. + # If +false+, don't validate the associated objects when saving the parent object. true by default. # [:autosave] # If true, always save the associated objects or destroy them if marked for destruction, # when saving the parent object. If false, never save or destroy the associated objects. @@ -1076,7 +1076,7 @@ module ActiveRecord # [:readonly] # If true, the associated object is readonly through the association. # [:validate] - # If false, don't validate the associated object when saving the parent object. +false+ by default. + # If +false+, don't validate the associated object when saving the parent object. +false+ by default. # [:autosave] # If true, always save the associated object or destroy it if marked for destruction, # when saving the parent object. If false, never save or destroy the associated object. @@ -1189,7 +1189,7 @@ module ActiveRecord # [:readonly] # If true, the associated object is readonly through the association. # [:validate] - # If false, don't validate the associated objects when saving the parent object. +false+ by default. + # If +false+, don't validate the associated objects when saving the parent object. +false+ by default. # [:autosave] # If true, always save the associated object or destroy it if marked for destruction, when # saving the parent object. @@ -1392,7 +1392,7 @@ module ActiveRecord # [:readonly] # If true, all the associated objects are readonly through the association. # [:validate] - # If false, don't validate the associated objects when saving the parent object. +true+ by default. + # If +false+, don't validate the associated objects when saving the parent object. +true+ by default. # [:autosave] # If true, always save the associated objects or destroy them if marked for destruction, when # saving the parent object. diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 1315914..5b890e5 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -112,8 +112,7 @@ module ActiveRecord # # === Validation # - # Validations on children records are run or not depending on the :validate - # option of the association. + # Children records are validated unless :validate is +false+. module AutosaveAssociation extend ActiveSupport::Concern -- 1.7.1 From e4283007d607454acf97301821ba1e1c417bdead Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 12 Aug 2010 13:32:00 -0700 Subject: [PATCH 106/805] It's snowing! --- .../lib/action_view/helpers/form_tag_helper.rb | 2 +- actionpack/test/template/form_helper_test.rb | 2 +- actionpack/test/template/form_tag_helper_test.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index c1c5db0..686c5b7 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -538,7 +538,7 @@ module ActionView def extra_tags_for_form(html_options) snowman_tag = tag(:input, :type => "hidden", - :name => "utf8", :value => "✓".html_safe) + :name => "_utf8", :value => "☃".html_safe) method = html_options.delete("method").to_s diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 71a5ae0..4c81e69 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -1513,7 +1513,7 @@ class FormHelperTest < ActionView::TestCase def snowman(method = nil) txt = %{
} - txt << %{} + txt << %{} txt << %{} if method txt << %{
} end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 532f086..d2f725a 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -12,7 +12,7 @@ class FormTagHelperTest < ActionView::TestCase method = options[:method] txt = %{
} - txt << %{} + txt << %{} txt << %{} if method txt << %{
} end -- 1.7.1 From fb6edb1769229fff66bf23a7c2e9d52cf26359c8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 12:28:41 -0700 Subject: [PATCH 107/805] symbol to proc is slow, we should avoid it --- .../has_and_belongs_to_many_association.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index bec123e..2838528 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -79,7 +79,7 @@ module ActiveRecord else relation = Arel::Table.new(@reflection.options[:join_table]) relation.where(relation[@reflection.primary_key_name].eq(@owner.id). - and(Arel::Predicates::In.new(relation[@reflection.association_foreign_key], records.map(&:id))) + and(Arel::Predicates::In.new(relation[@reflection.association_foreign_key], records.map { |x| x.id })) ).delete end end -- 1.7.1 From abd973689d3446dccbd39891a906440c35b06535 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 12:30:58 -0700 Subject: [PATCH 108/805] do not use arel constants directly --- .../has_and_belongs_to_many_association.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 2838528..be68aff 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -79,7 +79,7 @@ module ActiveRecord else relation = Arel::Table.new(@reflection.options[:join_table]) relation.where(relation[@reflection.primary_key_name].eq(@owner.id). - and(Arel::Predicates::In.new(relation[@reflection.association_foreign_key], records.map { |x| x.id })) + and(relation[@reflection.association_foreign_key].in(records.map { |x| x.id })) ).delete end end -- 1.7.1 From e86b7585928b9d673a0dc7f146819885c7a28667 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 12:32:17 -0700 Subject: [PATCH 109/805] avoiding symbol to proc again --- .../associations/has_many_association.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index c33bc6a..9a12a18 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -76,7 +76,7 @@ module ActiveRecord else relation = Arel::Table.new(@reflection.table_name) relation.where(relation[@reflection.primary_key_name].eq(@owner.id). - and(Arel::Predicates::In.new(relation[@reflection.klass.primary_key], records.map(&:id))) + and(Arel::Predicates::In.new(relation[@reflection.klass.primary_key], records.map { |r| r.id })) ).update(relation[@reflection.primary_key_name] => nil) @owner.class.update_counters(@owner.id, cached_counter_attribute_name => -records.size) if has_cached_counter? -- 1.7.1 From bacf78150c5fc7da4798d0158d2d17aaf63cf246 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 12:33:54 -0700 Subject: [PATCH 110/805] removing references to arel constants --- .../associations/has_many_association.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 9a12a18..ccc01d2 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -76,7 +76,7 @@ module ActiveRecord else relation = Arel::Table.new(@reflection.table_name) relation.where(relation[@reflection.primary_key_name].eq(@owner.id). - and(Arel::Predicates::In.new(relation[@reflection.klass.primary_key], records.map { |r| r.id })) + and(relation[@reflection.klass.primary_key].in(records.map { |r| r.id })) ).update(relation[@reflection.primary_key_name] => nil) @owner.class.update_counters(@owner.id, cached_counter_attribute_name => -records.size) if has_cached_counter? -- 1.7.1 From 108179b0689640e8913ebbef44316847750c70f7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 13:32:48 -0700 Subject: [PATCH 111/805] avoid direct use of arel constants --- .../lib/active_record/relation/spawn_methods.rb | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index f857e50..b4da8e4 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -22,8 +22,10 @@ module ActiveRecord merged_wheres = @where_values r.where_values.each do |w| - if w.is_a?(Arel::Predicates::Equality) - merged_wheres = merged_wheres.reject {|p| p.is_a?(Arel::Predicates::Equality) && p.operand1.name == w.operand1.name } + if w.respond_to?(:operator) && w.operator == :== + merged_wheres = merged_wheres.reject { |p| + p.respond_to?(:operator) && p.operator == :== && p.operand1.name == w.operand1.name + } end merged_wheres += [w] -- 1.7.1 From 3698da65e587c1c33e897c49d9204b3861f89d9d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 13 Aug 2010 17:34:20 -0300 Subject: [PATCH 112/805] Moves local_request? to require.local? [#5361 state:committed] --- actionpack/lib/action_dispatch/http/request.rb | 7 +++++++ .../action_dispatch/middleware/show_exceptions.rb | 9 +-------- railties/lib/rails/info_controller.rb | 2 +- railties/test/rails_info_controller_test.rb | 10 ++++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index fd23b1d..5606d6a 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -15,6 +15,8 @@ module ActionDispatch include ActionDispatch::Http::Upload include ActionDispatch::Http::URL + LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, "::1", /^0:0:0:0:0:0:0:1(%.*)?$/].freeze + %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_TRANSLATED REMOTE_HOST REMOTE_IDENT REMOTE_USER REMOTE_ADDR @@ -231,5 +233,10 @@ module ActionDispatch @env['X_HTTP_AUTHORIZATION'] || @env['REDIRECT_X_HTTP_AUTHORIZATION'] end + + # True if the request came from localhost, 127.0.0.1. + def local? + LOCALHOST.any? { |local_ip| local_ip === remote_addr && local_ip === remote_ip } + end end end diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index e095b51..a7d3cb4 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -6,8 +6,6 @@ module ActionDispatch # This middleware rescues any exception returned by the application and renders # nice exception pages if it's being rescued locally. class ShowExceptions - LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, "::1", /^0:0:0:0:0:0:0:1(%.*)?$/].freeze - RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates') cattr_accessor :rescue_responses @@ -66,7 +64,7 @@ module ActionDispatch log_error(exception) request = Request.new(env) - if @consider_all_requests_local || local_request?(request) + if @consider_all_requests_local || request.local? rescue_action_locally(request, exception) else rescue_action_in_public(exception) @@ -112,11 +110,6 @@ module ActionDispatch end end - # True if the request came from localhost, 127.0.0.1. - def local_request?(request) - LOCALHOST.any? { |local_ip| local_ip === request.remote_addr && local_ip === request.remote_ip } - end - def status_code(exception) Rack::Utils.status_code(@@rescue_responses[exception.class.name]) end diff --git a/railties/lib/rails/info_controller.rb b/railties/lib/rails/info_controller.rb index 196eeb4..6b4bdb2 100644 --- a/railties/lib/rails/info_controller.rb +++ b/railties/lib/rails/info_controller.rb @@ -1,6 +1,6 @@ class Rails::InfoController < ActionController::Base def properties - if consider_all_requests_local? || local_request? + if consider_all_requests_local? || request.local? render :inline => Rails::Info.to_html else render :text => '

For security purposes, this information is only available to local requests.

', :status => :forbidden diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb index 687c2d1..9d194f4 100644 --- a/railties/test/rails_info_controller_test.rb +++ b/railties/test/rails_info_controller_test.rb @@ -14,26 +14,28 @@ class InfoControllerTest < ActionController::TestCase Rails.application.routes.draw do match '/rails/info/properties' => "rails/info#properties" end - @controller.stubs(:consider_all_requests_local? => false, :local_request? => true) + @request.stubs(:local? => true) + @controller.stubs(:consider_all_requests_local? => false) @routes = Rails.application.routes Rails::InfoController.send(:include, @routes.url_helpers) end test "info controller does not allow remote requests" do - @controller.stubs(:consider_all_requests_local? => false, :local_request? => false) + @request.stubs(:local? => false) get :properties assert_response :forbidden end test "info controller renders an error message when request was forbidden" do - @controller.stubs(:consider_all_requests_local? => false, :local_request? => false) + @request.stubs(:local? => false) get :properties assert_select 'p' end test "info controller allows requests when all requests are considered local" do - @controller.stubs(:consider_all_requests_local? => true, :local_request? => false) + @request.stubs(:local? => false) + @controller.stubs(:consider_all_requests_local? => true) get :properties assert_response :success end -- 1.7.1 From 79e15f03408a4a624000a40975465c0d632b5c8c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 14:44:58 -0700 Subject: [PATCH 113/805] removing a lolinject --- .../lib/action_view/helpers/form_options_helper.rb | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index ee34452..3c4d0b6 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -300,12 +300,12 @@ module ActionView container = container.to_a if Hash === container selected, disabled = extract_selected_and_disabled(selected) - options_for_select = container.inject([]) do |options, element| + options_for_select = container.map do |element| html_attributes = option_html_attributes(element) text, value = option_text_and_value(element) selected_attribute = ' selected="selected"' if option_value_selected?(value, selected) disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled) - options << %() + %() end options_for_select.join("\n").html_safe -- 1.7.1 From 433d7a26fe4e68f78a2a606f1c1567c0597fc779 Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Sat, 14 Aug 2010 05:59:15 +0700 Subject: [PATCH 114/805] Removing most of the symbol to proc usage in Active Record This will hopefully make Active Record run a bit more faster. --- activerecord/lib/active_record/associations.rb | 12 ++++++------ .../has_and_belongs_to_many_association.rb | 2 +- .../lib/active_record/autosave_association.rb | 2 +- activerecord/lib/active_record/base.rb | 6 +++--- .../abstract/schema_definitions.rb | 2 +- .../abstract/schema_statements.rb | 2 +- .../connection_adapters/postgresql_adapter.rb | 2 +- .../connection_adapters/sqlite_adapter.rb | 6 +++--- activerecord/lib/active_record/fixtures.rb | 4 ++-- activerecord/lib/active_record/migration.rb | 6 +++--- activerecord/lib/active_record/observer.rb | 2 +- activerecord/lib/active_record/relation.rb | 4 ++-- .../lib/active_record/relation/finder_methods.rb | 2 +- activerecord/lib/active_record/schema_dumper.rb | 2 +- activerecord/lib/active_record/test_case.rb | 2 +- 15 files changed, 28 insertions(+), 28 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index c6aefdc..cfced3c 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -35,7 +35,7 @@ module ActiveRecord through_reflection = reflection.through_reflection source_reflection_names = reflection.source_reflection_names source_associations = reflection.through_reflection.klass.reflect_on_all_associations.collect { |a| a.name.inspect } - super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => '. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?") + super("Could not find the source association(s) #{source_reflection_names.collect{ |a| a.inspect }.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => '. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?") end end @@ -1497,17 +1497,17 @@ module ActiveRecord association end - + redefine_method("#{reflection.name.to_s.singularize}_ids") do if send(reflection.name).loaded? || reflection.options[:finder_sql] - send(reflection.name).map(&:id) + send(reflection.name).map { |r| r.id } else if reflection.through_reflection && reflection.source_reflection.belongs_to? through = reflection.through_reflection primary_key = reflection.source_reflection.primary_key_name - send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map!(&:"#{primary_key}") + send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map! { |r| r.send(:"#{primary_key}") } else - send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").except(:includes).map!(&:id) + send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").except(:includes).map! { |r| r.id } end end end @@ -1529,7 +1529,7 @@ module ActiveRecord pk_column = reflection.primary_key_column ids = (new_value || []).reject { |nid| nid.blank? } ids.map!{ |i| pk_column.type_cast(i) } - send("#{reflection.name}=", reflection.klass.find(ids).index_by(&:id).values_at(*ids)) + send("#{reflection.name}=", reflection.klass.find(ids).index_by{ |r| r.id }.values_at(*ids)) end end end diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index be68aff..4f9bd8f 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -127,7 +127,7 @@ module ActiveRecord def record_timestamp_columns(record) if record.record_timestamps - record.send(:all_timestamp_attributes).map(&:to_s) + record.send(:all_timestamp_attributes).map { |x| x.to_s } else [] end diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 5b890e5..5a35dc2 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -231,7 +231,7 @@ module ActiveRecord def nested_records_changed_for_autosave? self.class.reflect_on_all_autosave_associations.any? do |reflection| association = association_instance_get(reflection.name) - association && Array.wrap(association.target).any?(&:changed_for_autosave?) + association && Array.wrap(association.target).any? { |a| a.changed_for_autosave? } end end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 4b550eb..15af7b4 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -519,7 +519,7 @@ module ActiveRecord #:nodoc: # Attributes listed as readonly will be used to create a new record but update operations will # ignore these fields. def attr_readonly(*attributes) - write_inheritable_attribute(:attr_readonly, Set.new(attributes.map(&:to_s)) + (readonly_attributes || [])) + write_inheritable_attribute(:attr_readonly, Set.new(attributes.map { |a| a.to_s }) + (readonly_attributes || [])) end # Returns an array of all the attributes that have been specified as readonly. @@ -1286,7 +1286,7 @@ MSG table = Arel::Table.new(self.table_name, :engine => arel_engine, :as => default_table_name) builder = PredicateBuilder.new(arel_engine) - builder.build_from_hash(attrs, table).map(&:to_sql).join(' AND ') + builder.build_from_hash(attrs, table).map{ |b| b.to_sql }.join(' AND ') end alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions @@ -1737,7 +1737,7 @@ MSG klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass # in order to allow a date to be set without a year, we must keep the empty values. # Otherwise, we wouldn't be able to distinguish it from a date with an empty day. - values = values_with_empty_parameters.reject(&:nil?) + values = values_with_empty_parameters.reject { |v| v.nil? } if values.empty? send(name + "=", nil) 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 9118ceb..2472403 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -528,7 +528,7 @@ module ActiveRecord # concatenated together. This string can then be prepended and appended to # to generate the final SQL to create the table. def to_sql - @columns.map(&:to_sql) * ', ' + @columns.map { |c| c.to_sql } * ', ' end private 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 7dee685..2140388 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -450,7 +450,7 @@ module ActiveRecord version = version.to_i sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name) - migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i) + migrated = select_values("SELECT version FROM #{sm_table}").map { |v| v.to_i } versions = Dir["#{migrations_path}/[0-9]*_*.rb"].map do |filename| filename.split('/').last.split('_').first.to_i end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 6fae899..5046c2f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -879,7 +879,7 @@ module ActiveRecord # Construct a clean list of column names from the ORDER BY clause, removing # any ASC/DESC modifiers order_columns = order_by.split(',').collect { |s| s.split.first } - order_columns.delete_if(&:blank?) + order_columns.delete_if { |c| c.blank? } order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" } # Return a DISTINCT ON() clause that's distinct on the columns we want but includes diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 82ad0a3..0de73c4 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -40,11 +40,11 @@ module ActiveRecord include Comparable def initialize(version_string) - @version = version_string.split('.').map(&:to_i) + @version = version_string.split('.').map { |v| v.to_i } end def <=>(version_string) - @version <=> version_string.split('.').map(&:to_i) + @version <=> version_string.split('.').map { |v| v.to_i } end end @@ -345,7 +345,7 @@ module ActiveRecord name = name[5..-1] end - to_column_names = columns(to).map(&:name) + to_column_names = columns(to).map { |c| c.name } columns = index.columns.map {|c| rename[c] || c }.select do |column| to_column_names.include?(column) end diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 4e49e9f..7cec560 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -690,7 +690,7 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash) end def column_names - @column_names ||= @connection.columns(@table_name).collect(&:name) + @column_names ||= @connection.columns(@table_name).collect { |c| c.name } end def read_fixture_files @@ -908,7 +908,7 @@ module ActiveRecord def uses_transaction(*methods) @uses_transaction = [] unless defined?(@uses_transaction) - @uses_transaction.concat methods.map(&:to_s) + @uses_transaction.concat methods.map { |m| m.to_s } end def uses_transaction?(method) diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 5e272f0..7f26aa3 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -374,7 +374,7 @@ module ActiveRecord end def method_missing(method, *arguments, &block) - arg_list = arguments.map(&:inspect) * ', ' + arg_list = arguments.map{ |a| a.inspect } * ', ' say_with_time "#{method}(#{arg_list})" do unless arguments.empty? || method == :execute @@ -451,7 +451,7 @@ module ActiveRecord def get_all_versions table = Arel::Table.new(schema_migrations_table_name) - Base.connection.select_values(table.project(table['version']).to_sql).map(&:to_i).sort + Base.connection.select_values(table.project(table['version']).to_sql).map{ |v| v.to_i }.sort end def current_version @@ -569,7 +569,7 @@ module ActiveRecord klasses << migration end - migrations = migrations.sort_by(&:version) + migrations = migrations.sort_by { |m| m.version } down? ? migrations.reverse : migrations end end diff --git a/activerecord/lib/active_record/observer.rb b/activerecord/lib/active_record/observer.rb index 78bac55..e7fe9c3 100644 --- a/activerecord/lib/active_record/observer.rb +++ b/activerecord/lib/active_record/observer.rb @@ -122,7 +122,7 @@ module ActiveRecord end def define_callbacks(klass) - existing_methods = klass.instance_methods.map(&:to_sym) + existing_methods = klass.instance_methods.map { |m| m.to_sym } observer = self observer_name = observer.class.name.underscore.gsub('/', '__') diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 30be723..1db7f2a 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -375,7 +375,7 @@ module ActiveRecord def references_eager_loaded_tables? # always convert table names to downcase as in Oracle quoted table names are in uppercase - joined_tables = (tables_in_string(arel.joins(arel)) + [table.name, table.table_alias]).compact.map(&:downcase).uniq + joined_tables = (tables_in_string(arel.joins(arel)) + [table.name, table.table_alias]).compact.map{ |t| t.downcase }.uniq (tables_in_string(to_sql) - joined_tables).any? end @@ -383,7 +383,7 @@ module ActiveRecord return [] if string.blank? # always convert table names to downcase as in Oracle quoted table names are in uppercase # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries - string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map(&:downcase).uniq - ['raw_sql_'] + string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map{ |s| s.downcase }.uniq - ['raw_sql_'] end end diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 0c75acf..fc6728b 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -348,7 +348,7 @@ module ActiveRecord end def using_limitable_reflections?(reflections) - reflections.none?(&:collection?) + reflections.none? { |r| r.collection? } end end diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index e9af20e..4566410 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -123,7 +123,7 @@ HEADER end.compact # find all migration keys used in this table - keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map(&:keys).flatten + keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map{ |k| k.keys }.flatten # figure out the lengths for each column based on above keys lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max } diff --git a/activerecord/lib/active_record/test_case.rb b/activerecord/lib/active_record/test_case.rb index e61a378..ec529ef 100644 --- a/activerecord/lib/active_record/test_case.rb +++ b/activerecord/lib/active_record/test_case.rb @@ -21,7 +21,7 @@ module ActiveRecord patterns_to_match.each do |pattern| failed_patterns << pattern unless $queries_executed.any?{ |sql| pattern === sql } end - assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map(&:inspect).join(', ')} not found.#{$queries_executed.size == 0 ? '' : "\nQueries:\n#{$queries_executed.join("\n")}"}" + assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{$queries_executed.size == 0 ? '' : "\nQueries:\n#{$queries_executed.join("\n")}"}" end def assert_queries(num = 1) -- 1.7.1 From 59e63e76c30fe22bf64c1cb3e89e317ea0e95cd2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 13 Aug 2010 16:50:22 -0700 Subject: [PATCH 115/805] converting to a symbol is not necessary --- activerecord/lib/active_record/associations.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index cfced3c..34f2c17 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1505,7 +1505,7 @@ module ActiveRecord if reflection.through_reflection && reflection.source_reflection.belongs_to? through = reflection.through_reflection primary_key = reflection.source_reflection.primary_key_name - send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map! { |r| r.send(:"#{primary_key}") } + send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map! { |r| r.send(primary_key) } else send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").except(:includes).map! { |r| r.id } end -- 1.7.1 From 6373dd466f5c87da51051a4fa427c222c962e46b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 13 Aug 2010 21:18:36 -0300 Subject: [PATCH 116/805] This method is actually not used, it's implemented on the concrete adapters [#5331 state:committed] --- .../connection_adapters/abstract/query_cache.rb | 8 -------- 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 78fffaf..0ee61d0 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -57,14 +57,6 @@ module ActiveRecord end end - def columns(*) - if @query_cache_enabled - @query_cache["SHOW FIELDS FROM #{args.first}"] ||= super - else - super - end - end - private def cache_sql(sql) result = -- 1.7.1 From ccd4364a13d7a3af9eec7672e08d0682765f5b2f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 13 Aug 2010 22:15:15 -0300 Subject: [PATCH 117/805] Makes AR use AMo to_key implementation [#5249] --- .../active_record/attribute_methods/primary_key.rb | 6 ------ activerecord/test/cases/primary_keys_test.rb | 2 +- 2 files changed, 1 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index 82d94b8..365fdeb 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -3,12 +3,6 @@ module ActiveRecord module PrimaryKey extend ActiveSupport::Concern - # Returns this record's primary key value wrapped in an Array - # or nil if the record is a new_record? - def to_key - new_record? ? nil : [ id ] - end - module ClassMethods # Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the # primary_key_prefix_type setting, though. diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb index 1e44237..5cdcb05 100644 --- a/activerecord/test/cases/primary_keys_test.rb +++ b/activerecord/test/cases/primary_keys_test.rb @@ -26,7 +26,7 @@ class PrimaryKeysTest < ActiveRecord::TestCase def test_to_key_with_primary_key_after_destroy topic = Topic.find(1) topic.destroy - assert_equal [1], topic.to_key + assert_equal nil, topic.to_key end def test_integer_key -- 1.7.1 From 3270c58ebb3143b3ab3b349fe339cdd4587468ee Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sat, 14 Aug 2010 04:16:17 -0300 Subject: [PATCH 118/805] Deletes trailing whitespaces (over text files only find * -type f -exec sed 's/[ \t]*$//' -i {} \;) --- README.rdoc | 4 +- actionmailer/CHANGELOG | 8 +- actionmailer/README.rdoc | 22 +- actionmailer/lib/action_mailer/base.rb | 22 +- actionmailer/lib/action_mailer/delivery_methods.rb | 4 +- actionmailer/lib/action_mailer/mail_helper.rb | 4 +- actionmailer/lib/action_mailer/old_api.rb | 32 +- actionmailer/lib/action_mailer/tmail_compat.rb | 6 +- actionmailer/test/base_test.rb | 16 +- actionmailer/test/delivery_methods_test.rb | 6 +- actionmailer/test/fixtures/raw_email10 | 2 +- actionmailer/test/fixtures/raw_email2 | 2 +- actionmailer/test/fixtures/raw_email3 | 2 +- actionmailer/test/fixtures/raw_email5 | 2 +- actionmailer/test/fixtures/raw_email6 | 2 +- actionmailer/test/fixtures/raw_email8 | 2 +- actionmailer/test/fixtures/raw_email9 | 10 +- actionmailer/test/fixtures/templates/signed_up.erb | 2 +- .../custom_templating_extension.html.haml | 4 +- .../custom_templating_extension.text.haml | 4 +- .../test/fixtures/test_mailer/signed_up.html.erb | 2 +- .../url_test_mailer/signed_up_with_url.erb | 2 +- actionmailer/test/mailers/proc_mailer.rb | 6 +- actionmailer/test/old_base/mail_service_test.rb | 30 +- actionmailer/test/old_base/tmail_compat_test.rb | 2 +- actionmailer/test/old_base/url_test.rb | 2 +- actionmailer/test/test_helper_test.rb | 24 +- actionpack/CHANGELOG | 4 +- actionpack/README.rdoc | 4 +- actionpack/RUNNING_UNIT_TESTS | 4 +- actionpack/lib/abstract_controller/base.rb | 2 +- .../action_controller/metal/http_authentication.rb | 4 +- actionpack/lib/action_controller/middleware.rb | 2 +- actionpack/lib/action_controller/test_case.rb | 2 +- .../vendor/html-scanner/html/document.rb | 4 +- .../vendor/html-scanner/html/node.rb | 58 ++-- .../vendor/html-scanner/html/sanitizer.rb | 50 ++-- .../vendor/html-scanner/html/selector.rb | 2 +- .../vendor/html-scanner/html/tokenizer.rb | 16 +- actionpack/lib/action_dispatch/http/mime_type.rb | 20 +- actionpack/lib/action_dispatch/middleware/stack.rb | 2 +- actionpack/lib/action_dispatch/routing.rb | 8 +- actionpack/lib/action_view/helpers/debug_helper.rb | 2 +- .../lib/action_view/helpers/form_options_helper.rb | 16 +- .../lib/action_view/helpers/form_tag_helper.rb | 16 +- .../lib/action_view/helpers/number_helper.rb | 2 +- .../lib/action_view/helpers/raw_output_helper.rb | 2 +- .../lib/action_view/helpers/sanitize_helper.rb | 4 +- actionpack/lib/action_view/helpers/text_helper.rb | 4 +- .../lib/action_view/helpers/translation_helper.rb | 18 +- actionpack/lib/action_view/log_subscriber.rb | 2 +- actionpack/lib/action_view/template/handler.rb | 2 +- actionpack/lib/action_view/template/handlers.rb | 2 +- actionpack/lib/action_view/test_case.rb | 2 +- actionpack/lib/action_view/testing/resolvers.rb | 2 +- actionpack/test/abstract/callbacks_test.rb | 92 +++--- actionpack/test/abstract/helper_test.rb | 8 +- actionpack/test/abstract/translation_test.rb | 8 +- actionpack/test/abstract_unit.rb | 2 +- actionpack/test/controller/assert_select_test.rb | 2 +- actionpack/test/controller/base_test.rb | 12 +- actionpack/test/controller/dispatcher_test.rb | 2 +- actionpack/test/controller/filters_test.rb | 2 +- actionpack/test/controller/helper_test.rb | 14 +- .../controller/http_basic_authentication_test.rb | 6 +- .../controller/http_token_authentication_test.rb | 6 +- actionpack/test/controller/layout_test.rb | 4 +- actionpack/test/controller/mime_responds_test.rb | 10 +- actionpack/test/controller/new_base/etag_test.rb | 2 +- .../new_base/render_implicit_action_test.rb | 4 +- .../test/controller/new_base/render_layout_test.rb | 2 +- .../controller/new_base/render_partial_test.rb | 14 +- actionpack/test/controller/new_base/render_test.rb | 2 +- .../test/controller/new_base/render_text_test.rb | 24 +- .../test/controller/new_base/render_xml_test.rb | 2 +- actionpack/test/controller/render_test.rb | 4 +- actionpack/test/controller/rescue_test.rb | 2 +- actionpack/test/controller/selector_test.rb | 8 +- actionpack/test/controller/test_test.rb | 2 +- actionpack/test/controller/view_paths_test.rb | 4 +- actionpack/test/dispatch/callbacks_test.rb | 2 +- actionpack/test/dispatch/mount_test.rb | 2 +- actionpack/test/dispatch/request_test.rb | 2 +- .../test/dispatch/session/cookie_store_test.rb | 8 +- .../test/dispatch/session/mem_cache_store_test.rb | 2 +- actionpack/test/fixtures/companies.yml | 2 +- actionpack/test/fixtures/company.rb | 2 +- actionpack/test/fixtures/db_definitions/sqlite.sql | 20 +- actionpack/test/fixtures/replies.yml | 2 +- .../test/fixtures/test/hello_xml_world.builder | 2 +- actionpack/test/fixtures/topics.yml | 2 +- .../test/template/compiled_templates_test.rb | 2 +- actionpack/test/template/date_helper_i18n_test.rb | 2 +- actionpack/test/template/date_helper_test.rb | 28 +- actionpack/test/template/erb_util_test.rb | 2 +- .../test/template/form_options_helper_test.rb | 12 +- .../test/template/html-scanner/document_test.rb | 2 +- actionpack/test/template/html-scanner/node_test.rb | 18 +- .../test/template/html-scanner/sanitizer_test.rb | 34 +- .../test/template/html-scanner/tag_node_test.rb | 46 ++-- .../test/template/html-scanner/text_node_test.rb | 10 +- .../test/template/html-scanner/tokenizer_test.rb | 20 +- actionpack/test/template/number_helper_test.rb | 2 +- actionpack/test/template/tag_helper_test.rb | 6 +- actionpack/test/template/text_helper_test.rb | 12 +- .../test/template/translation_helper_test.rb | 8 +- actionpack/test/template/url_helper_test.rb | 4 +- activemodel/CHANGELOG | 2 +- activemodel/README.rdoc | 54 ++-- activemodel/lib/active_model/attribute_methods.rb | 84 +++--- activemodel/lib/active_model/callbacks.rb | 58 ++-- activemodel/lib/active_model/conversion.rb | 12 +- activemodel/lib/active_model/dirty.rb | 36 +- activemodel/lib/active_model/errors.rb | 60 ++-- activemodel/lib/active_model/lint.rb | 2 +- activemodel/lib/active_model/naming.rb | 10 +- activemodel/lib/active_model/observing.rb | 14 +- activemodel/lib/active_model/serialization.rb | 44 ++-- activemodel/lib/active_model/serializers/xml.rb | 2 +- activemodel/lib/active_model/translation.rb | 14 +- activemodel/lib/active_model/validations.rb | 32 +- .../lib/active_model/validations/acceptance.rb | 22 +- .../lib/active_model/validations/confirmation.rb | 20 +- activemodel/lib/active_model/validations/length.rb | 2 +- .../lib/active_model/validations/validates.rb | 10 +- activemodel/lib/active_model/validator.rb | 22 +- activemodel/test/cases/attribute_methods_test.rb | 4 +- .../serializeration/json_serialization_test.rb | 10 +- activemodel/test/cases/translation_test.rb | 4 +- .../test/cases/validations/validates_test.rb | 8 +- activemodel/test/cases/validations_test.rb | 2 +- activemodel/test/models/custom_reader.rb | 4 +- activemodel/test/models/person_with_validator.rb | 2 +- activemodel/test/models/sheep.rb | 1 - activerecord/README.rdoc | 18 +- activerecord/RUNNING_UNIT_TESTS | 16 +- activerecord/lib/active_record/aggregations.rb | 96 +++--- .../lib/active_record/association_preload.rb | 8 +- activerecord/lib/active_record/associations.rb | 342 ++++++++++---------- .../has_and_belongs_to_many_association.rb | 6 +- .../associations/has_many_association.rb | 8 +- .../associations/has_many_through_association.rb | 6 +- .../attribute_methods/time_zone_conversion.rb | 2 +- .../lib/active_record/attribute_methods/write.rb | 2 +- .../lib/active_record/autosave_association.rb | 10 +- activerecord/lib/active_record/base.rb | 174 +++++----- activerecord/lib/active_record/callbacks.rb | 48 ++-- .../abstract/connection_pool.rb | 2 +- .../abstract/schema_definitions.rb | 6 +- .../abstract/schema_statements.rb | 4 +- .../connection_adapters/mysql2_adapter.rb | 4 +- .../connection_adapters/mysql_adapter.rb | 2 +- .../connection_adapters/postgresql_adapter.rb | 8 +- .../connection_adapters/sqlite_adapter.rb | 2 +- .../lib/active_record/dynamic_finder_match.rb | 2 +- .../lib/active_record/dynamic_scope_match.rb | 2 +- activerecord/lib/active_record/errors.rb | 8 +- activerecord/lib/active_record/fixtures.rb | 36 +- activerecord/lib/active_record/locale/en.yml | 4 +- activerecord/lib/active_record/migration.rb | 66 ++-- activerecord/lib/active_record/named_scope.rb | 24 +- .../lib/active_record/nested_attributes.rb | 2 +- activerecord/lib/active_record/observer.rb | 2 +- activerecord/lib/active_record/reflection.rb | 26 +- activerecord/lib/active_record/relation.rb | 8 +- .../lib/active_record/relation/calculations.rb | 52 ++-- .../lib/active_record/relation/finder_methods.rb | 14 +- .../lib/active_record/relation/spawn_methods.rb | 2 +- activerecord/lib/active_record/schema_dumper.rb | 4 +- activerecord/lib/active_record/serialization.rb | 2 +- .../active_record/serializers/xml_serializer.rb | 2 +- activerecord/lib/active_record/session_store.rb | 2 +- activerecord/lib/active_record/test_case.rb | 2 +- .../lib/active_record/validations/associated.rb | 4 +- .../lib/active_record/validations/uniqueness.rb | 20 +- .../has_many_through_associations_test.rb | 4 +- .../has_one_through_associations_test.rb | 14 +- .../test/cases/associations/join_model_test.rb | 10 +- activerecord/test/cases/associations_test.rb | 6 +- activerecord/test/cases/attribute_methods_test.rb | 8 +- .../test/cases/autosave_association_test.rb | 2 +- activerecord/test/cases/counter_cache_test.rb | 2 +- activerecord/test/cases/defaults_test.rb | 6 +- activerecord/test/cases/dirty_test.rb | 14 +- activerecord/test/cases/fixtures_test.rb | 16 +- activerecord/test/cases/i18n_test.rb | 4 +- activerecord/test/cases/json_serialization_test.rb | 2 +- activerecord/test/cases/migration_test.rb | 4 +- activerecord/test/cases/modules_test.rb | 4 +- activerecord/test/cases/nested_attributes_test.rb | 20 +- activerecord/test/cases/persistence_test.rb | 4 +- activerecord/test/cases/reflection_test.rb | 2 +- activerecord/test/cases/relation_scoping_test.rb | 4 +- activerecord/test/cases/relations_test.rb | 4 +- activerecord/test/cases/serialization_test.rb | 2 +- activerecord/test/cases/timestamp_test.rb | 28 +- activerecord/test/fixtures/comments.yml | 4 +- activerecord/test/fixtures/companies.yml | 10 +- activerecord/test/fixtures/items.yml | 1 - activerecord/test/fixtures/memberships.yml | 2 +- activerecord/test/fixtures/mixins.yml | 2 +- activerecord/test/fixtures/taggings.yml | 2 +- activerecord/test/fixtures/tags.yml | 2 +- activerecord/test/models/developer.rb | 2 +- activerecord/test/models/minivan.rb | 4 +- activerecord/test/models/post.rb | 2 +- activerecord/test/models/shop.rb | 2 +- activerecord/test/models/topic.rb | 2 +- .../test/schema/postgresql_specific_schema.rb | 2 +- activerecord/test/schema/schema.rb | 6 +- activeresource/CHANGELOG | 22 +- activeresource/README.rdoc | 8 +- activeresource/lib/active_resource/http_mock.rb | 8 +- activeresource/lib/active_resource/validations.rb | 16 +- .../test/cases/base/custom_methods_test.rb | 10 +- activeresource/test/cases/validations_test.rb | 2 +- activeresource/test/connection_test.rb | 4 +- activesupport/CHANGELOG | 68 ++-- activesupport/lib/active_support/base64.rb | 6 +- activesupport/lib/active_support/benchmarkable.rb | 6 +- activesupport/lib/active_support/cache.rb | 22 +- .../active_support/cache/strategy/local_cache.rb | 2 +- activesupport/lib/active_support/callbacks.rb | 2 +- .../active_support/core_ext/array/random_access.rb | 8 +- .../lib/active_support/core_ext/array/wrap.rb | 2 +- .../active_support/core_ext/date/calculations.rb | 4 +- .../core_ext/date_time/conversions.rb | 12 +- .../lib/active_support/core_ext/date_time/zones.rb | 2 +- .../lib/active_support/core_ext/enumerable.rb | 8 +- .../active_support/core_ext/hash/conversions.rb | 22 +- .../lib/active_support/core_ext/integer/time.rb | 4 +- .../active_support/core_ext/module/anonymous.rb | 2 +- .../core_ext/module/attr_accessor_with_default.rb | 4 +- .../core_ext/module/attribute_accessors.rb | 2 +- .../core_ext/module/remove_method.rb | 2 +- .../core_ext/module/synchronization.rb | 4 +- .../lib/active_support/core_ext/numeric/time.rb | 18 +- .../lib/active_support/core_ext/object/blank.rb | 2 +- .../core_ext/object/instance_variables.rb | 10 +- .../active_support/core_ext/object/returning.rb | 4 +- .../active_support/core_ext/range/conversions.rb | 2 +- .../lib/active_support/core_ext/string/access.rb | 14 +- .../active_support/core_ext/string/inflections.rb | 12 +- .../active_support/core_ext/time/calculations.rb | 4 +- .../active_support/core_ext/time/conversions.rb | 2 +- .../lib/active_support/core_ext/time/zones.rb | 6 +- activesupport/lib/active_support/duration.rb | 2 +- activesupport/lib/active_support/i18n_railtie.rb | 2 +- .../lib/active_support/lazy_load_hooks.rb | 4 +- activesupport/lib/active_support/locale/en.yml | 6 +- activesupport/lib/active_support/log_subscriber.rb | 2 +- .../active_support/log_subscriber/test_helper.rb | 2 +- .../lib/active_support/message_encryptor.rb | 34 +- .../lib/active_support/message_verifier.rb | 14 +- activesupport/lib/active_support/multibyte.rb | 2 +- .../lib/active_support/testing/assertions.rb | 4 +- .../lib/active_support/testing/declarative.rb | 8 +- .../lib/active_support/testing/pending.rb | 6 +- activesupport/lib/active_support/time_with_zone.rb | 4 +- activesupport/lib/active_support/xml_mini/rexml.rb | 2 +- .../class_folder/nested_class.rb | 2 +- activesupport/test/clean_backtrace_test.rb | 14 +- activesupport/test/clean_logger_test.rb | 4 +- activesupport/test/core_ext/array_ext_test.rb | 12 +- .../test/core_ext/class/attribute_accessor_test.rb | 10 +- .../class/class_inheritable_attributes_test.rb | 22 +- activesupport/test/core_ext/date_ext_test.rb | 16 +- activesupport/test/core_ext/date_time_ext_test.rb | 2 +- activesupport/test/core_ext/duration_test.rb | 4 +- activesupport/test/core_ext/enumerable_test.rb | 2 +- activesupport/test/core_ext/hash_ext_test.rb | 42 ++-- activesupport/test/core_ext/kernel_test.rb | 2 +- .../test/core_ext/module/anonymous_test.rb | 2 +- .../module/attr_accessor_with_default_test.rb | 8 +- .../core_ext/module/attribute_accessor_test.rb | 2 +- .../core_ext/module/attribute_aliasing_test.rb | 6 +- .../test/core_ext/module/reachable_test.rb | 16 +- activesupport/test/core_ext/numeric_ext_test.rb | 24 +- .../test/core_ext/object_and_class_ext_test.rb | 2 +- activesupport/test/core_ext/string_ext_test.rb | 2 +- activesupport/test/core_ext/time_ext_test.rb | 20 +- activesupport/test/core_ext/time_with_zone_test.rb | 6 +- activesupport/test/i18n_test.rb | 34 +- activesupport/test/message_encryptor_test.rb | 14 +- activesupport/test/multibyte_conformance.rb | 30 +- activesupport/test/option_merger_test.rb | 2 +- activesupport/test/rescuable_test.rb | 8 +- activesupport/test/test_test.rb | 20 +- activesupport/test/time_zone_test.rb | 2 +- ci/ci_setup_notes.txt | 6 +- ci/site_config.rb | 12 +- railties/CHANGELOG | 150 +++++----- railties/README.rdoc | 2 +- railties/guides/assets/stylesheets/main.css | 28 +- railties/guides/rails_guides/generator.rb | 14 +- railties/guides/source/2_3_release_notes.textile | 10 +- .../source/action_controller_overview.textile | 14 +- .../guides/source/action_view_overview.textile | 88 +++--- .../guides/source/active_record_basics.textile | 4 +- .../guides/source/active_record_querying.textile | 12 +- .../active_record_validations_callbacks.textile | 40 ++-- .../source/active_support_core_extensions.textile | 16 +- railties/guides/source/ajax_on_rails.textile | 34 +- .../source/api_documentation_guidelines.textile | 4 +- railties/guides/source/association_basics.textile | 4 +- railties/guides/source/caching_with_rails.textile | 10 +- railties/guides/source/command_line.textile | 4 +- railties/guides/source/configuring.textile | 10 +- railties/guides/source/getting_started.textile | 22 +- railties/guides/source/i18n.textile | 2 +- railties/guides/source/initialization.textile | 110 ++++---- .../guides/source/layouts_and_rendering.textile | 18 +- railties/guides/source/nested_model_forms.textile | 14 +- railties/guides/source/plugins.textile | 2 +- .../source/rails_application_templates.textile | 4 +- railties/guides/source/routing.textile | 4 +- railties/guides/source/security.textile | 2 +- railties/guides/w3c_validator.rb | 18 +- railties/lib/rails/code_statistics.rb | 8 +- railties/lib/rails/generators/base.rb | 2 +- .../app/templates/public/javascripts/effects.js | 2 +- .../lib/rails/generators/rails/generator/USAGE | 2 +- .../lib/rails/generators/rails/migration/USAGE | 8 +- railties/lib/rails/generators/rails/plugin/USAGE | 2 +- .../rails/resource/resource_generator.rb | 4 +- railties/lib/rails/plugin.rb | 2 +- railties/lib/rails/railtie.rb | 4 +- railties/lib/rails/script_rails_loader.rb | 4 +- railties/lib/rails/tasks/documentation.rake | 8 +- railties/test/application/loading_test.rb | 6 +- railties/test/application/rake_test.rb | 2 +- railties/test/generators/actions_test.rb | 4 +- railties/test/generators/app_generator_test.rb | 2 +- railties/test/railties/railtie_test.rb | 2 +- railties/test/script_rails_loader_test.rb | 8 +- 335 files changed, 2116 insertions(+), 2118 deletions(-) diff --git a/README.rdoc b/README.rdoc index 090a6bb..2e5e72c 100644 --- a/README.rdoc +++ b/README.rdoc @@ -34,7 +34,7 @@ link:files/vendor/rails/actionpack/README.html. 2. At the command prompt, create a new Rails application: - rails new myapp + rails new myapp where "myapp" is the application name. @@ -48,7 +48,7 @@ link:files/vendor/rails/actionpack/README.html. "Welcome aboard: You're riding Ruby on Rails!" -5. Follow the guidelines to start developing your application. You can find +5. Follow the guidelines to start developing your application. You can find the following resources handy: * The README file created within your application. diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index 76eab93..d2cc70f 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -181,7 +181,7 @@ * ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, Marcel Molina Jr.] -* Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.] +* Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.] * Replace Ruby's deprecated append_features in favor of included. [Marcel Molina Jr.] @@ -327,7 +327,7 @@ * Added that deliver_* will now return the email that was sent -* Added that quoting to UTF-8 only happens if the characters used are in that range #955 [Jamis Buck] +* Added that quoting to UTF-8 only happens if the characters used are in that range #955 [Jamis Buck] * Fixed quoting for all address headers, not just to #955 [Jamis Buck] @@ -366,7 +366,7 @@ @body = "Nothing to see here." @charset = "iso-8859-1" end - + def unencoded_subject(recipient) @recipients = recipient @subject = "testing unencoded subject" @@ -375,7 +375,7 @@ @encode_subject = false @charset = "iso-8859-1" end - + *0.6.1* (January 18th, 2005) diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc index 602326e..dfb696e 100644 --- a/actionmailer/README.rdoc +++ b/actionmailer/README.rdoc @@ -5,7 +5,7 @@ are used to consolidate code for sending out forgotten passwords, welcome wishes on signup, invoices for billing, and any other use case that requires a written notification to either a person or another system. -Action Mailer is in essence a wrapper around Action Controller and the +Action Mailer is in essence a wrapper around Action Controller and the Mail gem. It provides a way to make emails using templates in the same way that Action Controller renders views using templates. @@ -23,7 +23,7 @@ This can be as simple as: class Notifier < ActionMailer::Base delivers_from 'system@loudthinking.com' - + def welcome(recipient) @recipient = recipient mail(:to => recipient, @@ -36,13 +36,13 @@ ERb) that has the instance variables that are declared in the mailer action. So the corresponding body template for the method above could look like this: - Hello there, + Hello there, Mr. <%= @recipient %> Thank you for signing up! - -And if the recipient was given as "david@loudthinking.com", the email + +And if the recipient was given as "david@loudthinking.com", the email generated would look like this: Date: Mon, 25 Jan 2010 22:48:09 +1100 @@ -55,7 +55,7 @@ generated would look like this: charset="US-ASCII"; Content-Transfer-Encoding: 7bit - Hello there, + Hello there, Mr. david@loudthinking.com @@ -75,7 +75,7 @@ Or you can just chain the methods together like: == Receiving emails To receive emails, you need to implement a public instance method called receive that takes a -tmail object as its single parameter. The Action Mailer framework has a corresponding class method, +tmail object as its single parameter. The Action Mailer framework has a corresponding class method, which is also called receive, that accepts a raw, unprocessed email as a string, which it then turns into the tmail object and calls the receive instance method. @@ -90,7 +90,7 @@ Example: if email.has_attachments? for attachment in email.attachments - page.attachments.create({ + page.attachments.create({ :file => attachment, :description => email.subject }) end @@ -98,13 +98,13 @@ Example: end end -This Mailman can be the target for Postfix or other MTAs. In Rails, you would use the runner in the +This Mailman can be the target for Postfix or other MTAs. In Rails, you would use the runner in the trivial case like this: rails runner 'Mailman.receive(STDIN.read)' -However, invoking Rails in the runner for each mail to be received is very resource intensive. A single -instance of Rails should be run within a daemon if it is going to be utilized to process more than just +However, invoking Rails in the runner for each mail to be received is very resource intensive. A single +instance of Rails should be run within a daemon if it is going to be utilized to process more than just a limited number of email. == Configuration diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index f742f98..8fe5868 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -187,31 +187,31 @@ module ActionMailer #:nodoc: # with the filename +free_book.pdf+. # # = Inline Attachments - # - # You can also specify that a file should be displayed inline with other HTML. This is useful + # + # You can also specify that a file should be displayed inline with other HTML. This is useful # if you want to display a corporate logo or a photo. - # + # # class ApplicationMailer < ActionMailer::Base # def welcome(recipient) # attachments.inline['photo.png'] = File.read('path/to/photo.png') # mail(:to => recipient, :subject => "Here is what we look like") # end # end - # + # # And then to reference the image in the view, you create a welcome.html.erb file and - # make a call to +image_tag+ passing in the attachment you want to display and then call + # make a call to +image_tag+ passing in the attachment you want to display and then call # +url+ on the attachment to get the relative content id path for the image source: - # + # #

Please Don't Cringe

- # + # # <%= image_tag attachments['photo.png'].url -%> - # + # # As we are using Action View's +image_tag+ method, you can pass in any other options you want: - # + # #

Please Don't Cringe

- # + # # <%= image_tag attachments['photo.png'].url, :alt => 'Our Photo', :class => 'photo' -%> - # + # # = Observing and Intercepting Mails # # Action Mailer provides hooks into the Mail observer and interceptor methods. These allow you to diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 043794b..b324ba7 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -46,11 +46,11 @@ module ActionMailer # as alias and the default options supplied: # # Example: - # + # # add_delivery_method :sendmail, Mail::Sendmail, # :location => '/usr/sbin/sendmail', # :arguments => '-i -t' - # + # def add_delivery_method(symbol, klass, default_options={}) class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings") send(:"#{symbol}_settings=", default_options) diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index b708881..80ffc9b 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -15,11 +15,11 @@ module ActionMailer :columns => 72, :first_indent => 2, :body_indent => 2, :text => paragraph ).format }.join("\n") - + # Make list points stand on their own line formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { |s| " #{$1} #{$2.strip}\n" } formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { |s| " #{$1} #{$2.strip}\n" } - + formatted end diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb index 79d024a..2a6289c 100644 --- a/actionmailer/lib/action_mailer/old_api.rb +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -116,36 +116,36 @@ module ActionMailer def normalize_nonfile_hash(params) content_disposition = "attachment;" - + mime_type = params.delete(:mime_type) - + if content_type = params.delete(:content_type) content_type = "#{mime_type || content_type};" end params[:body] = params.delete(:data) if params[:data] - + { :content_type => content_type, :content_disposition => content_disposition }.merge(params) end - + def normalize_file_hash(params) filename = File.basename(params.delete(:filename)) content_disposition = "attachment; filename=\"#{File.basename(filename)}\"" - + mime_type = params.delete(:mime_type) - + if (content_type = params.delete(:content_type)) && (content_type !~ /filename=/) content_type = "#{mime_type || content_type}; filename=\"#{filename}\"" end - + params[:body] = params.delete(:data) if params[:data] - + { :content_type => content_type, :content_disposition => content_disposition }.merge(params) end - def create_mail + def create_mail m = @_message set_fields!({:subject => subject, :to => recipients, :from => from, @@ -178,14 +178,14 @@ module ActionMailer wrap_delivery_behavior! m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? - + @_message end - + # Set up the default values for the various instance variables of this # mailer. Subclasses may override this method to provide different # defaults. - def initialize_defaults(method_name) + def initialize_defaults(method_name) @charset ||= self.class.default[:charset].try(:dup) @content_type ||= self.class.default[:content_type].try(:dup) @implicit_parts_order ||= self.class.default[:parts_order].try(:dup) @@ -201,7 +201,7 @@ module ActionMailer @body ||= {} end - def create_parts + def create_parts if String === @body @parts.unshift create_inline_part(@body) elsif @parts.empty? || @parts.all? { |p| p.content_disposition =~ /^attachment/ } @@ -220,7 +220,7 @@ module ActionMailer end end - def create_inline_part(body, mime_type=nil) + def create_inline_part(body, mime_type=nil) ct = mime_type || "text/plain" main_type, sub_type = split_content_type(ct.to_s) @@ -242,11 +242,11 @@ module ActionMailer m.reply_to ||= headers.delete(:reply_to) if headers[:reply_to] end - def split_content_type(ct) + def split_content_type(ct) ct.to_s.split("/") end - def parse_content_type(defaults=nil) + def parse_content_type(defaults=nil) if @content_type.blank? [ nil, {} ] else diff --git a/actionmailer/lib/action_mailer/tmail_compat.rb b/actionmailer/lib/action_mailer/tmail_compat.rb index 26962f9..26cc474 100644 --- a/actionmailer/lib/action_mailer/tmail_compat.rb +++ b/actionmailer/lib/action_mailer/tmail_compat.rb @@ -1,12 +1,12 @@ module Mail class Message - + def set_content_type(*args) ActiveSupport::Deprecation.warn('Message#set_content_type is deprecated, please just call ' << 'Message#content_type with the same arguments', caller[0,2]) content_type(*args) end - + alias :old_transfer_encoding :transfer_encoding def transfer_encoding(value = nil) if value @@ -29,6 +29,6 @@ module Mail 'please call Message#filename', caller[0,2]) filename end - + end end \ No newline at end of file diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index fec0ecf..fb42ccb 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -148,7 +148,7 @@ class BaseTest < ActiveSupport::TestCase assert_equal("application/pdf", email.parts[1].mime_type) assert_equal("VGhpcyBpcyB0ZXN0IEZpbGUgY29udGVudA==\r\n", email.parts[1].body.encoded) end - + test "can embed an inline attachment" do email = BaseMailer.inline_attachment # Need to call #encoded to force the JIT sort on parts @@ -413,7 +413,7 @@ class BaseTest < ActiveSupport::TestCase BaseMailer.welcome.deliver assert_equal(1, BaseMailer.deliveries.length) end - + test "calling deliver, ActionMailer should yield back to mail to let it call :do_delivery on itself" do mail = Mail::Message.new mail.expects(:do_delivery).once @@ -447,7 +447,7 @@ class BaseTest < ActiveSupport::TestCase mail = BaseMailer.welcome_from_another_path(['unknown/invalid', 'another.path/base_mailer']).deliver assert_equal("Welcome from another path", mail.body.encoded) end - + test "assets tags should use ActionMailer's asset_host settings" do ActionMailer::Base.config.asset_host = "http://global.com" ActionMailer::Base.config.assets_dir = "global/" @@ -456,7 +456,7 @@ class BaseTest < ActiveSupport::TestCase assert_equal(%{Dummy}, mail.body.to_s.strip) end - + test "assets tags should use a Mailer's asset_host settings when available" do ActionMailer::Base.config.asset_host = "global.com" ActionMailer::Base.config.assets_dir = "global/" @@ -469,12 +469,12 @@ class BaseTest < ActiveSupport::TestCase end # Before and After hooks - + class MyObserver def self.delivered_email(mail) end end - + test "you can register an observer to the mail object that gets informed on email delivery" do ActionMailer::Base.register_observer(MyObserver) mail = BaseMailer.welcome @@ -493,7 +493,7 @@ class BaseTest < ActiveSupport::TestCase MyInterceptor.expects(:delivering_email).with(mail) mail.deliver end - + test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do mail1 = ProcMailer.welcome yesterday = 1.day.ago @@ -501,7 +501,7 @@ class BaseTest < ActiveSupport::TestCase mail2 = ProcMailer.welcome assert(mail1['X-Proc-Method'].to_s.to_i > mail2['X-Proc-Method'].to_s.to_i) end - + test "we can call other defined methods on the class as needed" do mail = ProcMailer.welcome assert_equal("Thanks for signing up this afternoon", mail.subject) diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index 22a7d19..08f84db 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -128,7 +128,7 @@ class MailDeliveryTest < ActiveSupport::TestCase Mail::Message.any_instance.expects(:deliver!).never DeliveryMailer.welcome.deliver end - + test "does not append the deliveries collection if told not to perform the delivery" do DeliveryMailer.perform_deliveries = false DeliveryMailer.deliveries.clear @@ -160,7 +160,7 @@ class MailDeliveryTest < ActiveSupport::TestCase DeliveryMailer.welcome.deliver end end - + test "does not increment the deliveries collection on bogus deliveries" do DeliveryMailer.delivery_method = BogusDelivery DeliveryMailer.raise_delivery_errors = false @@ -168,5 +168,5 @@ class MailDeliveryTest < ActiveSupport::TestCase DeliveryMailer.welcome.deliver assert_equal(0, DeliveryMailer.deliveries.length) end - + end diff --git a/actionmailer/test/fixtures/raw_email10 b/actionmailer/test/fixtures/raw_email10 index b1fc2b2..edad5cc 100644 --- a/actionmailer/test/fixtures/raw_email10 +++ b/actionmailer/test/fixtures/raw_email10 @@ -15,6 +15,6 @@ Content-Type: text/plain; charset=X-UNKNOWN Test test. Hi. Waving. m ---------------------------------------------------------------- -Sent via Bell Mobility's Text Messaging service. +Sent via Bell Mobility's Text Messaging service. Envoyé par le service de messagerie texte de Bell Mobilité. ---------------------------------------------------------------- diff --git a/actionmailer/test/fixtures/raw_email2 b/actionmailer/test/fixtures/raw_email2 index 3999fcc..9f87bb2 100644 --- a/actionmailer/test/fixtures/raw_email2 +++ b/actionmailer/test/fixtures/raw_email2 @@ -32,7 +32,7 @@ To: xxxxx xxxx Subject: Fwd: Signed email causes file attachments In-Reply-To: Mime-Version: 1.0 -Content-Type: multipart/mixed; +Content-Type: multipart/mixed; boundary="----=_Part_5028_7368284.1115579351471" References: diff --git a/actionmailer/test/fixtures/raw_email3 b/actionmailer/test/fixtures/raw_email3 index 771a963..3a09274 100644 --- a/actionmailer/test/fixtures/raw_email3 +++ b/actionmailer/test/fixtures/raw_email3 @@ -31,7 +31,7 @@ Reply-To: Test Tester To: xxxx@xxxx.com, xxxx@xxxx.com Subject: Another PDF Mime-Version: 1.0 -Content-Type: multipart/mixed; +Content-Type: multipart/mixed; boundary="----=_Part_2192_32400445.1115745999735" X-Virus-Scanned: amavisd-new at textdrive.com diff --git a/actionmailer/test/fixtures/raw_email5 b/actionmailer/test/fixtures/raw_email5 index 151c631..bbe31bc 100644 --- a/actionmailer/test/fixtures/raw_email5 +++ b/actionmailer/test/fixtures/raw_email5 @@ -14,6 +14,6 @@ Importance: normal Test test. Hi. Waving. m ---------------------------------------------------------------- -Sent via Bell Mobility's Text Messaging service. +Sent via Bell Mobility's Text Messaging service. Envoyé par le service de messagerie texte de Bell Mobilité. ---------------------------------------------------------------- diff --git a/actionmailer/test/fixtures/raw_email6 b/actionmailer/test/fixtures/raw_email6 index 93289c4..8e37bd7 100644 --- a/actionmailer/test/fixtures/raw_email6 +++ b/actionmailer/test/fixtures/raw_email6 @@ -15,6 +15,6 @@ Content-Type: text/plain; charset=us-ascii Test test. Hi. Waving. m ---------------------------------------------------------------- -Sent via Bell Mobility's Text Messaging service. +Sent via Bell Mobility's Text Messaging service. Envoyé par le service de messagerie texte de Bell Mobilité. ---------------------------------------------------------------- diff --git a/actionmailer/test/fixtures/raw_email8 b/actionmailer/test/fixtures/raw_email8 index 2382dfd..7999636 100644 --- a/actionmailer/test/fixtures/raw_email8 +++ b/actionmailer/test/fixtures/raw_email8 @@ -8,7 +8,7 @@ To: xxxxx xxxx Subject: Fwd: Signed email causes file attachments In-Reply-To: Mime-Version: 1.0 -Content-Type: multipart/mixed; +Content-Type: multipart/mixed; boundary="----=_Part_5028_7368284.1115579351471" References: diff --git a/actionmailer/test/fixtures/raw_email9 b/actionmailer/test/fixtures/raw_email9 index 8b9b1ea..02ea0b0 100644 --- a/actionmailer/test/fixtures/raw_email9 +++ b/actionmailer/test/fixtures/raw_email9 @@ -10,19 +10,19 @@ Date: Wed, 23 Feb 2005 18:20:17 -0400 From: "xxx xxx" Message-ID: <4D6AA7EB.6490534@xxx.xxx> To: xxx@xxx.com -Subject: Stop adware/spyware once and for all. +Subject: Stop adware/spyware once and for all. X-Scanned-By: MIMEDefang 2.11 (www dot roaringpenguin dot com slash mimedefang) -You are infected with: +You are infected with: Ad Ware and Spy Ware -Get your free scan and removal download now, -before it gets any worse. +Get your free scan and removal download now, +before it gets any worse. http://xxx.xxx.info?aid=3D13&?stat=3D4327kdzt -no more? (you will still be infected) +no more? (you will still be infected) http://xxx.xxx.info/discon/?xxx@xxx.com diff --git a/actionmailer/test/fixtures/templates/signed_up.erb b/actionmailer/test/fixtures/templates/signed_up.erb index a85d5fa..7afe1f6 100644 --- a/actionmailer/test/fixtures/templates/signed_up.erb +++ b/actionmailer/test/fixtures/templates/signed_up.erb @@ -1,3 +1,3 @@ -Hello there, +Hello there, Mr. <%= @recipient %> \ No newline at end of file diff --git a/actionmailer/test/fixtures/test_mailer/custom_templating_extension.html.haml b/actionmailer/test/fixtures/test_mailer/custom_templating_extension.html.haml index 847d065..8dcf974 100644 --- a/actionmailer/test/fixtures/test_mailer/custom_templating_extension.html.haml +++ b/actionmailer/test/fixtures/test_mailer/custom_templating_extension.html.haml @@ -1,6 +1,6 @@ -%p Hello there, +%p Hello there, -%p +%p Mr. = @recipient from haml \ No newline at end of file diff --git a/actionmailer/test/fixtures/test_mailer/custom_templating_extension.text.haml b/actionmailer/test/fixtures/test_mailer/custom_templating_extension.text.haml index 847d065..8dcf974 100644 --- a/actionmailer/test/fixtures/test_mailer/custom_templating_extension.text.haml +++ b/actionmailer/test/fixtures/test_mailer/custom_templating_extension.text.haml @@ -1,6 +1,6 @@ -%p Hello there, +%p Hello there, -%p +%p Mr. = @recipient from haml \ No newline at end of file diff --git a/actionmailer/test/fixtures/test_mailer/signed_up.html.erb b/actionmailer/test/fixtures/test_mailer/signed_up.html.erb index a85d5fa..7afe1f6 100644 --- a/actionmailer/test/fixtures/test_mailer/signed_up.html.erb +++ b/actionmailer/test/fixtures/test_mailer/signed_up.html.erb @@ -1,3 +1,3 @@ -Hello there, +Hello there, Mr. <%= @recipient %> \ No newline at end of file diff --git a/actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb b/actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb index 4c5806d..6e7875c 100644 --- a/actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb +++ b/actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb @@ -1,4 +1,4 @@ -Hello there, +Hello there, Mr. <%= @recipient %>. Please see our greeting at <%= @welcome_url %> <%= welcome_url %> diff --git a/actionmailer/test/mailers/proc_mailer.rb b/actionmailer/test/mailers/proc_mailer.rb index 6a79cd7..43916e1 100644 --- a/actionmailer/test/mailers/proc_mailer.rb +++ b/actionmailer/test/mailers/proc_mailer.rb @@ -6,11 +6,11 @@ class ProcMailer < ActionMailer::Base def welcome mail end - + private - + def give_a_greeting "Thanks for signing up this afternoon" end - + end diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb index 831adf3..4c93eb6 100644 --- a/actionmailer/test/old_base/mail_service_test.rb +++ b/actionmailer/test/old_base/mail_service_test.rb @@ -106,7 +106,7 @@ class TestMailer < ActionMailer::Base cc "Foo áëô îü " bcc "Foo áëô îü " charset "UTF-8" - + body "åœö blah" end @@ -359,7 +359,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal "text/plain", created.parts[0].parts[0].mime_type assert_equal "text/html", created.parts[0].parts[1].mime_type assert_equal "application/octet-stream", created.parts[1].mime_type - + end def test_nested_parts_with_body @@ -399,7 +399,7 @@ class ActionMailerTest < Test::Unit::TestCase created = nil assert_nothing_raised { created = TestMailer.signed_up(@recipient) } assert_not_nil created - + expected.message_id = '<123@456>' created.message_id = '<123@456>' @@ -503,7 +503,7 @@ class ActionMailerTest < Test::Unit::TestCase delivered = ActionMailer::Base.deliveries.first expected.message_id = '<123@456>' delivered.message_id = '<123@456>' - + assert_equal expected.encoded, delivered.encoded end @@ -546,10 +546,10 @@ class ActionMailerTest < Test::Unit::TestCase created = TestMailer.different_reply_to @recipient end assert_not_nil created - + expected.message_id = '<123@456>' created.message_id = '<123@456>' - + assert_equal expected.encoded, created.encoded assert_nothing_raised do @@ -558,10 +558,10 @@ class ActionMailerTest < Test::Unit::TestCase delivered = ActionMailer::Base.deliveries.first assert_not_nil delivered - + expected.message_id = '<123@456>' delivered.message_id = '<123@456>' - + assert_equal expected.encoded, delivered.encoded end @@ -581,7 +581,7 @@ class ActionMailerTest < Test::Unit::TestCase created = TestMailer.iso_charset @recipient end assert_not_nil created - + expected.message_id = '<123@456>' created.message_id = '<123@456>' @@ -596,7 +596,7 @@ class ActionMailerTest < Test::Unit::TestCase expected.message_id = '<123@456>' delivered.message_id = '<123@456>' - + assert_equal expected.encoded, delivered.encoded end @@ -631,7 +631,7 @@ class ActionMailerTest < Test::Unit::TestCase expected.message_id = '<123@456>' delivered.message_id = '<123@456>' - + assert_equal expected.encoded, delivered.encoded end @@ -761,10 +761,10 @@ EOF delivered = ActionMailer::Base.deliveries.first assert_not_nil delivered - + expected.message_id = '<123@456>' delivered.message_id = '<123@456>' - + assert_equal expected.encoded, delivered.encoded end @@ -887,7 +887,7 @@ EOF assert_equal "iso-8859-1", mail.parts[1].charset assert_equal "image/jpeg", mail.parts[2].mime_type - + assert_equal "attachment", mail.parts[2][:content_disposition].disposition_type assert_equal "foo.jpg", mail.parts[2][:content_disposition].filename assert_equal "foo.jpg", mail.parts[2][:content_type].filename @@ -1005,7 +1005,7 @@ EOF attachment = mail.attachments.last expected = "01 Quien Te Dij\212at. Pitbull.mp3" - + if expected.respond_to?(:force_encoding) result = attachment.filename.dup expected.force_encoding(Encoding::ASCII_8BIT) diff --git a/actionmailer/test/old_base/tmail_compat_test.rb b/actionmailer/test/old_base/tmail_compat_test.rb index 255205d..23706e9 100644 --- a/actionmailer/test/old_base/tmail_compat_test.rb +++ b/actionmailer/test/old_base/tmail_compat_test.rb @@ -31,5 +31,5 @@ class TmailCompatTest < ActiveSupport::TestCase end assert_equal mail.content_transfer_encoding, "base64" end - + end diff --git a/actionmailer/test/old_base/url_test.rb b/actionmailer/test/old_base/url_test.rb index b6496bf..b4be7df 100644 --- a/actionmailer/test/old_base/url_test.rb +++ b/actionmailer/test/old_base/url_test.rb @@ -83,7 +83,7 @@ class ActionMailerUrlTest < ActionMailer::TestCase assert_nothing_raised { UrlTestMailer.signed_up_with_url(@recipient).deliver } assert_not_nil ActionMailer::Base.deliveries.first delivered = ActionMailer::Base.deliveries.first - + delivered.message_id = '<123@456>' assert_equal expected.encoded, delivered.encoded end diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 8ff604c..5a101e8 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -32,7 +32,7 @@ class TestHelperMailerTest < ActionMailer::TestCase self.class.determine_default_mailer("NotAMailerTest") end end - + def test_charset_is_utf_8 assert_equal "UTF-8", charset end @@ -44,14 +44,14 @@ class TestHelperMailerTest < ActionMailer::TestCase end end end - + def test_repeated_assert_emails_calls assert_nothing_raised do assert_emails 1 do TestHelperMailer.test.deliver end end - + assert_nothing_raised do assert_emails 2 do TestHelperMailer.test.deliver @@ -59,20 +59,20 @@ class TestHelperMailerTest < ActionMailer::TestCase end end end - + def test_assert_emails_with_no_block assert_nothing_raised do TestHelperMailer.test.deliver assert_emails 1 end - + assert_nothing_raised do TestHelperMailer.test.deliver TestHelperMailer.test.deliver assert_emails 3 end end - + def test_assert_no_emails assert_nothing_raised do assert_no_emails do @@ -80,17 +80,17 @@ class TestHelperMailerTest < ActionMailer::TestCase end end end - + def test_assert_emails_too_few_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_emails 2 do TestHelperMailer.test.deliver end end - + assert_match(/2 .* but 1/, error.message) end - + def test_assert_emails_too_many_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_emails 1 do @@ -98,17 +98,17 @@ class TestHelperMailerTest < ActionMailer::TestCase TestHelperMailer.test.deliver end end - + assert_match(/1 .* but 2/, error.message) end - + def test_assert_no_emails_failure error = assert_raise ActiveSupport::TestCase::Assertion do assert_no_emails do TestHelperMailer.test.deliver end end - + assert_match(/0 .* but 1/, error.message) end end diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 81abb8b..dce2e30 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -26,7 +26,7 @@ resources :comments end end - + You can now use comment_path for /comments/1 instead of post_comment_path for /posts/1/comments/1. * Add support for multi-subdomain session by setting cookie host in session cookie so you can share session between www.example.com, example.com and user.example.com. #4818 [Guillermo Álvarez] @@ -110,7 +110,7 @@ * ActionDispatch::Request#content_type returns a String to be compatible with Rack::Request. Use #content_mime_type for the Mime::Type instance [YK] -* Updated Prototype to 1.6.1 and Scriptaculous to 1.8.3 [ML] +* Updated Prototype to 1.6.1 and Scriptaculous to 1.8.3 [ML] * Change the preferred way that URL helpers are included into a class[YK & CL] diff --git a/actionpack/README.rdoc b/actionpack/README.rdoc index b297ceb..0ad33cf 100644 --- a/actionpack/README.rdoc +++ b/actionpack/README.rdoc @@ -102,10 +102,10 @@ A short rundown of some of the major features: class WeblogController < ActionController::Base # filters as methods before_filter :authenticate, :cache, :audit - + # filter as a proc after_filter { |c| c.response.body = Gzip::compress(c.response.body) } - + # class filter after_filter LocalizeFilter diff --git a/actionpack/RUNNING_UNIT_TESTS b/actionpack/RUNNING_UNIT_TESTS index 95a8bc7..d6a1ccf 100644 --- a/actionpack/RUNNING_UNIT_TESTS +++ b/actionpack/RUNNING_UNIT_TESTS @@ -1,7 +1,7 @@ == Running with Rake The easiest way to run the unit tests is through Rake. The default task runs -the entire test suite for all classes. For more information, checkout the +the entire test suite for all classes. For more information, checkout the full array of rake tasks with "rake -T" Rake can be found at http://rake.rubyforge.org @@ -16,7 +16,7 @@ you can do so with something like: == Dependency on ActiveRecord and database setup Test cases in the test/controller/active_record/ directory depend on having -activerecord and sqlite installed. If ActiveRecord is not in +activerecord and sqlite installed. If ActiveRecord is not in actionpack/../activerecord directory, or the sqlite rubygem is not installed, these tests are skipped. diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index db0a673..79ebf29 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -109,7 +109,7 @@ module AbstractController @_action_name = action_name = action.to_s unless action_name = method_for_action(action_name) - raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}" + raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}" end @_response_body = nil diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index b0eb24a..acd313b 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -392,11 +392,11 @@ module ActionController end end - # If token Authorization header is present, call the login procedure with + # If token Authorization header is present, call the login procedure with # the present token and options. # # controller - ActionController::Base instance for the current request. - # login_procedure - Proc to call if a token is present. The Proc should + # login_procedure - Proc to call if a token is present. The Proc should # take 2 arguments: # authenticate(controller) { |token, options| ... } # diff --git a/actionpack/lib/action_controller/middleware.rb b/actionpack/lib/action_controller/middleware.rb index 2115b07..437fec3 100644 --- a/actionpack/lib/action_controller/middleware.rb +++ b/actionpack/lib/action_controller/middleware.rb @@ -31,7 +31,7 @@ module ActionController super() @_app = app end - + def index call(env) end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index e306697..e02fe20 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -311,7 +311,7 @@ module ActionController def tests(controller_class) self.controller_class = controller_class end - + def controller_class=(new_class) prepare_controller_class(new_class) if new_class write_inheritable_attribute(:controller_class, new_class) diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb index b8d73c3..7fa3aea 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb @@ -48,7 +48,7 @@ EOF end end end - + # Search the tree for (and return) the first node that matches the given # conditions. The conditions are interpreted differently for different node # types, see HTML::Text#find and HTML::Tag#find. @@ -62,7 +62,7 @@ EOF def find_all(conditions) @root.find_all(conditions) end - + end end diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb index a874519..d581399 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb @@ -1,7 +1,7 @@ require 'strscan' module HTML #:nodoc: - + class Conditions < Hash #:nodoc: def initialize(hash) super() @@ -57,17 +57,17 @@ module HTML #:nodoc: class Node #:nodoc: # The array of children of this node. Not all nodes have children. attr_reader :children - + # The parent node of this node. All nodes have a parent, except for the # root node. attr_reader :parent - + # The line number of the input where this node was begun attr_reader :line - + # The byte position in the input where this node was begun attr_reader :position - + # Create a new node as a child of the given parent. def initialize(parent, line=0, pos=0) @parent = parent @@ -92,7 +92,7 @@ module HTML #:nodoc: # returns non +nil+. Returns the result of the #find call that succeeded. def find(conditions) conditions = validate_conditions(conditions) - @children.each do |child| + @children.each do |child| node = child.find(conditions) return node if node end @@ -133,7 +133,7 @@ module HTML #:nodoc: equivalent end - + class </) if strict - raise "expected > (got #{scanner.rest.inspect} for #{content}, #{attributes.inspect})" + raise "expected > (got #{scanner.rest.inspect} for #{content}, #{attributes.inspect})" else # throw away all text until we find what we're looking for scanner.skip_until(/>/) or scanner.terminate @@ -212,9 +212,9 @@ module HTML #:nodoc: # A node that represents text, rather than markup. class Text < Node #:nodoc: - + attr_reader :content - + # Creates a new text node as a child of the given parent, with the given # content. def initialize(parent, line, pos, content) @@ -240,7 +240,7 @@ module HTML #:nodoc: def find(conditions) match(conditions) && self end - + # Returns non-+nil+ if this node meets the given conditions, or +nil+ # otherwise. See the discussion of #find for the valid conditions. def match(conditions) @@ -268,7 +268,7 @@ module HTML #:nodoc: content == node.content end end - + # A CDATA node is simply a text node with a specialized way of displaying # itself. class CDATA < Text #:nodoc: @@ -281,16 +281,16 @@ module HTML #:nodoc: # closing tag, or a self-closing tag. It has a name, and may have a hash of # attributes. class Tag < Node #:nodoc: - + # Either +nil+, :close, or :self attr_reader :closing - + # Either +nil+, or a hash of attributes for this node. attr_reader :attributes # The name of this tag. attr_reader :name - + # Create a new node as a child of the given parent, using the given content # to describe the node. It will be parsed and the node name, attributes and # closing status extracted. @@ -344,7 +344,7 @@ module HTML #:nodoc: def tag? true end - + # Returns +true+ if the node meets any of the given conditions. The # +conditions+ parameter must be a hash of any of the following keys # (all are optional): @@ -404,7 +404,7 @@ module HTML #:nodoc: # node.match :descendant => { :tag => "strong" } # # # test if the node has between 2 and 4 span tags as immediate children - # node.match :children => { :count => 2..4, :only => { :tag => "span" } } + # node.match :children => { :count => 2..4, :only => { :tag => "span" } } # # # get funky: test to see if the node is a "div", has a "ul" ancestor # # and an "li" parent (with "class" = "enum"), and whether or not it has @@ -439,7 +439,7 @@ module HTML #:nodoc: # test children return false unless children.find { |child| child.match(conditions[:child]) } if conditions[:child] - + # test ancestors if conditions[:ancestor] return false unless catch :found do @@ -457,13 +457,13 @@ module HTML #:nodoc: child.match(:descendant => conditions[:descendant]) end end - + # count children if opts = conditions[:children] matches = children.select do |c| (c.kind_of?(HTML::Tag) and (c.closing == :self or ! c.childless?)) end - + matches = matches.select { |c| c.match(opts[:only]) } if opts[:only] opts.each do |key, value| next if key == :only @@ -489,24 +489,24 @@ module HTML #:nodoc: self_index = siblings.index(self) if conditions[:sibling] - return false unless siblings.detect do |s| + return false unless siblings.detect do |s| s != self && s.match(conditions[:sibling]) end end if conditions[:before] - return false unless siblings[self_index+1..-1].detect do |s| + return false unless siblings[self_index+1..-1].detect do |s| s != self && s.match(conditions[:before]) end end if conditions[:after] - return false unless siblings[0,self_index].detect do |s| + return false unless siblings[0,self_index].detect do |s| s != self && s.match(conditions[:after]) end end end - + true end @@ -515,7 +515,7 @@ module HTML #:nodoc: return false unless closing == node.closing && self.name == node.name attributes == node.attributes end - + private # Match the given value to the given condition. def match_condition(value, condition) 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 51e0868..dceddb9 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb @@ -7,11 +7,11 @@ module HTML return text unless sanitizeable?(text) tokenize(text, options).join end - + def sanitizeable?(text) !(text.nil? || text.empty? || !text.index("<")) end - + protected def tokenize(text, options) tokenizer = HTML::Tokenizer.new(text) @@ -22,12 +22,12 @@ module HTML end result end - + def process_node(node, result, options) result << node.to_s end end - + class FullSanitizer < Sanitizer def sanitize(text, options = {}) result = super @@ -37,12 +37,12 @@ module HTML # Recurse - handle all dirty nested tags result == text ? result : sanitize(result, options) end - + def process_node(node, result, options) result << node.to_s if node.class == HTML::Text end end - + class LinkSanitizer < FullSanitizer cattr_accessor :included_tags, :instance_writer => false self.included_tags = Set.new(%w(a href)) @@ -50,13 +50,13 @@ module HTML def sanitizeable?(text) !(text.nil? || text.empty? || !((text.index(""))) end - + protected def process_node(node, result, options) - result << node.to_s unless node.is_a?(HTML::Tag) && included_tags.include?(node.name) + result << node.to_s unless node.is_a?(HTML::Tag) && included_tags.include?(node.name) end end - + class WhiteListSanitizer < Sanitizer [:protocol_separator, :uri_attributes, :allowed_attributes, :allowed_tags, :allowed_protocols, :bad_tags, :allowed_css_properties, :allowed_css_keywords, :shorthand_css_properties].each do |attr| @@ -66,35 +66,35 @@ module HTML # A regular expression of the valid characters used to separate protocols like # the ':' in 'http://foo.com' self.protocol_separator = /:|(�*58)|(p)|(%|%)3A/ - + # Specifies a Set of HTML attributes that can have URIs. self.uri_attributes = Set.new(%w(href src cite action longdesc xlink:href lowsrc)) # Specifies a Set of 'bad' tags that the #sanitize helper will remove completely, as opposed # to just escaping harmless tags like <font> self.bad_tags = Set.new(%w(script)) - + # Specifies the default Set of tags that the #sanitize helper will allow unscathed. - self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var sub - sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr + self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var sub + sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr acronym a img blockquote del ins)) - # Specifies the default Set of html attributes that the #sanitize helper will leave + # Specifies the default Set of html attributes that the #sanitize helper will leave # in the allowed tag. self.allowed_attributes = Set.new(%w(href src width height alt cite datetime title class name xml:lang abbr)) - + # Specifies the default Set of acceptable css properties that #sanitize and #sanitize_css will accept. - self.allowed_protocols = Set.new(%w(ed2k ftp http https irc mailto news gopher nntp telnet webcal xmpp callto + 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. - 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 + 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 overflow pause pause-after pause-before pitch pitch-range richness speak speak-header speak-numeral speak-punctuation speech-rate stress text-align text-decoration text-indent unicode-bidi vertical-align voice-family volume white-space width)) - + # Specifies the default Set of acceptable css keywords that #sanitize and #sanitize_css will accept. self.allowed_css_keywords = Set.new(%w(auto aqua black block blue bold both bottom brown center collapse dashed dotted fuchsia gray green !important italic left lime maroon medium none navy normal @@ -118,9 +118,9 @@ module HTML style.scan(/([-\w]+)\s*:\s*([^:;]*)/) do |prop,val| if allowed_css_properties.include?(prop.downcase) clean << prop + ': ' + val + ';' - elsif shorthand_css_properties.include?(prop.split('-')[0].downcase) + elsif shorthand_css_properties.include?(prop.split('-')[0].downcase) unless val.split().any? do |keyword| - !allowed_css_keywords.include?(keyword) && + !allowed_css_keywords.include?(keyword) && keyword !~ /^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$/ end clean << prop + ': ' + val + ';' @@ -146,7 +146,7 @@ module HTML else options[:parent].unshift node.name end - + process_attributes_for node, options options[:tags].include?(node.name) ? node : nil @@ -154,7 +154,7 @@ module HTML bad_tags.include?(options[:parent].first) ? nil : node.to_s.gsub(/:not. For example: # p:not(.post) # Matches all paragraphs that do not have the class .post. - # + # # === Substitution Values # # You can use substitution with identifiers, class names and element values. diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb index 240dc18..c252e01 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb @@ -1,7 +1,7 @@ require 'strscan' module HTML #:nodoc: - + # A simple HTML tokenizer. It simply breaks a stream of text into tokens, where each # token is a string. Each string represents either "text", or an HTML element. # @@ -14,13 +14,13 @@ module HTML #:nodoc: # p token # end class Tokenizer #:nodoc: - + # The current (byte) position in the text attr_reader :position - + # The current line number attr_reader :line - + # Create a new Tokenizer for the given text. def initialize(text) text.encode! if text.encoding_aware? @@ -42,7 +42,7 @@ module HTML #:nodoc: update_current_line(scan_text) end end - + private # Treat the text at the current position as a tag, and scan it. Supports @@ -69,13 +69,13 @@ module HTML #:nodoc: def scan_text "#{@scanner.getch}#{@scanner.scan(/[^<]*/)}" end - + # Counts the number of newlines in the text and updates the current line # accordingly. def update_current_line(text) text.scan(/\r?\n/) { @current_line += 1 } end - + # Skips over quoted strings, so that less-than and greater-than characters # within the strings are ignored. def consume_quoted_regions @@ -103,5 +103,5 @@ module HTML #:nodoc: text end end - + end diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index c6fc582..8f1c9b6 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -109,10 +109,10 @@ module Mime else # keep track of creation order to keep the subsequent sort stable list = [] - accept_header.split(/,/).each_with_index do |header, index| - params, q = header.split(/;\s*q=/) + accept_header.split(/,/).each_with_index do |header, index| + params, q = header.split(/;\s*q=/) if params - params.strip! + params.strip! list << AcceptItem.new(index, params, q) unless params.empty? end end @@ -161,20 +161,20 @@ module Mime end end end - + def initialize(string, symbol = nil, synonyms = []) @symbol, @synonyms = symbol, synonyms @string = string end - + def to_s @string end - + def to_str to_s end - + def to_sym @symbol || @string.to_sym end @@ -186,11 +186,11 @@ module Mime super end end - + def ==(mime_type) return false if mime_type.blank? - (@synonyms + [ self ]).any? do |synonym| - synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym + (@synonyms + [ self ]).any? do |synonym| + synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym end end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 41078ec..5a029a6 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -69,7 +69,7 @@ module ActionDispatch end def active - ActiveSupport::Deprecation.warn "All middlewares in the chain are active since the laziness " << + ActiveSupport::Deprecation.warn "All middlewares in the chain are active since the laziness " << "was removed from the middleware stack", caller end diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 683dd72..df1b530 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -15,7 +15,7 @@ module ActionDispatch # match ':controller(/:action(/:id(.:format)))' # # This route states that it expects requests to consist of a - # :controller followed optionally by an :action that in + # :controller followed optionally by an :action that in # turn is followed optionally by an :id, which in turn is followed # optionally by a :format # @@ -134,8 +134,8 @@ module ActionDispatch # == HTTP Methods # # Using the :via option when specifying a route allows you to restrict it to a specific HTTP method. - # Possible values are :post, :get, :put, :delete and :any. - # If your route needs to respond to more than one method you can use an array, e.g. [ :get, :post ]. + # Possible values are :post, :get, :put, :delete and :any. + # If your route needs to respond to more than one method you can use an array, e.g. [ :get, :post ]. # The default value is :any which means that the route will respond to any of the HTTP methods. # # Examples: @@ -144,7 +144,7 @@ module ActionDispatch # match 'post/:id' => "posts#create_comment', :via => :post # # Now, if you POST to /posts/:id, it will route to the create_comment action. A GET on the same - # URL will route to the show action. + # URL will route to the show action. # # === HTTP helper methods # diff --git a/actionpack/lib/action_view/helpers/debug_helper.rb b/actionpack/lib/action_view/helpers/debug_helper.rb index 1491cb0..cd67851 100644 --- a/actionpack/lib/action_view/helpers/debug_helper.rb +++ b/actionpack/lib/action_view/helpers/debug_helper.rb @@ -1,6 +1,6 @@ module ActionView # = Action View Debug Helper - # + # # Provides a set of methods for making it easier to debug Rails objects. module Helpers module DebugHelper diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 3c4d0b6..698cd3e 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -53,16 +53,16 @@ module ActionView # # # - # - # Like the other form helpers, +select+ can accept an :index option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this + # + # Like the other form helpers, +select+ can accept an :index option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this # option to be in the +html_options+ parameter. - # - # Example: - # + # + # Example: + # # select("album[]", "genre", %w[rap rock country], {}, { :index => nil }) - # + # # becomes: - # + # # - # + # # <%= form_tag('/posts', :remote => true) %> # # =>
- # + # def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block) html_options = html_options_for_form(url_for_options, options, *parameters_for_url) if block_given? @@ -351,12 +351,12 @@ module ActionView # Creates a submit button with the text value as the caption. # # ==== Options - # * :confirm => 'question?' - If present the unobtrusive JavaScript - # drivers will provide a prompt with the question specified. If the user accepts, + # * :confirm => 'question?' - If present the unobtrusive JavaScript + # drivers will provide a prompt with the question specified. If the user accepts, # the form is processed normally, otherwise no action is taken. # * :disabled - If true, the user will not be able to use this input. - # * :disable_with - Value of this parameter will be used as the value for a - # disabled version of the submit button when the form is submitted. This feature is + # * :disable_with - Value of this parameter will be used as the value for a + # disabled version of the submit button when the form is submitted. This feature is # provided by the unobtrusive JavaScript driver. # * Any other key creates standard HTML options for the tag. # @@ -383,7 +383,7 @@ module ActionView # # name="commit" type="submit" value="Edit" /> # # submit_tag "Save", :confirm => "Are you sure?" - # # => # def submit_tag(value = "Save changes", options = {}) diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index f11027b..9dc4727 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -325,7 +325,7 @@ module ActionView defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {}) defaults = defaults.merge(human) - + options = options.reverse_merge(defaults) #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros) diff --git a/actionpack/lib/action_view/helpers/raw_output_helper.rb b/actionpack/lib/action_view/helpers/raw_output_helper.rb index da7599f..216683a 100644 --- a/actionpack/lib/action_view/helpers/raw_output_helper.rb +++ b/actionpack/lib/action_view/helpers/raw_output_helper.rb @@ -2,7 +2,7 @@ module ActionView #:nodoc: # = Action View Raw Output Helper module Helpers #:nodoc: module RawOutputHelper - # This method outputs without escaping a string. Since escaping tags is + # This method outputs without escaping a string. Since escaping tags is # now default, this can be used when you don't want Rails to automatically # escape tags. This is not recommended if the data is coming from the user's # input. diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index d82005f..0fee34f 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -9,7 +9,7 @@ module ActionView # These helper methods extend Action View making them callable within your template files. module SanitizeHelper extend ActiveSupport::Concern - # This +sanitize+ helper will html encode all tags and strip all attributes that + # This +sanitize+ helper will html encode all tags and strip all attributes that # aren't specifically allowed. # # It also strips href/src tags with invalid protocols, like javascript: especially. @@ -21,7 +21,7 @@ module ActionView # # You can add or remove tags/attributes if you want to customize it a bit. # See ActionView::Base for full docs on the available options. You can add - # tags/attributes for single uses of +sanitize+ by passing either the + # tags/attributes for single uses of +sanitize+ by passing either the # :attributes or :tags options: # # Normal Use diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index c1de5c8..46af301 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -462,7 +462,7 @@ module ActionView text.gsub(AUTO_LINK_RE) do scheme, href = $1, $& punctuation = [] - + if auto_linked?($`, $') # do not change string; URL is already linked href @@ -507,7 +507,7 @@ module ActionView end end end - + # Detects already linked context or position in the middle of a tag def auto_linked?(left, right) (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index dac9c28..13767a0 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -5,21 +5,21 @@ module ActionView module Helpers module TranslationHelper # Delegates to I18n#translate but also performs three additional functions. - # First, it'll catch MissingTranslationData exceptions and turn them into - # inline spans that contains the missing key, such that you can see in a + # First, it'll catch MissingTranslationData exceptions and turn them into + # inline spans that contains the missing key, such that you can see in a # view what is missing where. # - # Second, it'll scope the key by the current partial if the key starts - # with a period. So if you call translate(".foo") from the - # people/index.html.erb template, you'll actually be calling + # Second, it'll scope the key by the current partial if the key starts + # with a period. So if you call translate(".foo") from the + # people/index.html.erb template, you'll actually be calling # I18n.translate("people.index.foo"). This makes it less repetitive # to translate many keys within the same partials and gives you a simple framework - # for scoping them consistently. If you don't prepend the key with a period, + # for scoping them consistently. If you don't prepend the key with a period, # nothing is converted. # - # Third, it'll mark the translation as safe HTML if the key has the suffix - # "_html" or the last element of the key is the word "html". For example, - # calling translate("footer_html") or translate("footer.html") will return + # Third, it'll mark the translation as safe HTML if the key has the suffix + # "_html" or the last element of the key is the word "html". For example, + # calling translate("footer_html") or translate("footer.html") will return # a safe HTML string that won't be escaped by other HTML helper methods. This # naming convention helps to identify translations that include HTML tags so that # you know what kind of output to expect when you call translate in a template. diff --git a/actionpack/lib/action_view/log_subscriber.rb b/actionpack/lib/action_view/log_subscriber.rb index 443a0ea..29ffbd6 100644 --- a/actionpack/lib/action_view/log_subscriber.rb +++ b/actionpack/lib/action_view/log_subscriber.rb @@ -7,7 +7,7 @@ module ActionView message = "Rendered #{from_rails_root(event.payload[:identifier])}" message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] message << (" (%.1fms)" % event.duration) - info(message) + info(message) end alias :render_partial :render_template alias :render_collection :render_template diff --git a/actionpack/lib/action_view/template/handler.rb b/actionpack/lib/action_view/template/handler.rb index 8ecc911..c6a1bc6 100644 --- a/actionpack/lib/action_view/template/handler.rb +++ b/actionpack/lib/action_view/template/handler.rb @@ -35,7 +35,7 @@ module ActionView end end end - + TemplateHandlers = Template::Handlers TemplateHandler = Template::Handler end diff --git a/actionpack/lib/action_view/template/handlers.rb b/actionpack/lib/action_view/template/handlers.rb index 84d6474..ed39769 100644 --- a/actionpack/lib/action_view/template/handlers.rb +++ b/actionpack/lib/action_view/template/handlers.rb @@ -18,7 +18,7 @@ module ActionView #:nodoc: @@template_handlers = {} @@default_template_handlers = nil - + def self.extensions @@template_extensions ||= @@template_handlers.keys end diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 137281e..e9d2e0b 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -44,7 +44,7 @@ module ActionView include ActionView::Helpers attr_accessor :controller, :output_buffer, :rendered - + module ClassMethods def tests(helper_class) self.helper_class = helper_class diff --git a/actionpack/lib/action_view/testing/resolvers.rb b/actionpack/lib/action_view/testing/resolvers.rb index 578c56c..97de247 100644 --- a/actionpack/lib/action_view/testing/resolvers.rb +++ b/actionpack/lib/action_view/testing/resolvers.rb @@ -38,6 +38,6 @@ module ActionView #:nodoc: [ActionView::Template.new("Template generated by Null Resolver", path, handler, :virtual_path => path, :format => format)] end end - + end diff --git a/actionpack/test/abstract/callbacks_test.rb b/actionpack/test/abstract/callbacks_test.rb index 232a167..b2d4d5f 100644 --- a/actionpack/test/abstract/callbacks_test.rb +++ b/actionpack/test/abstract/callbacks_test.rb @@ -2,23 +2,23 @@ require 'abstract_unit' module AbstractController module Testing - + class ControllerWithCallbacks < AbstractController::Base include AbstractController::Callbacks end - + class Callback1 < ControllerWithCallbacks set_callback :process_action, :before, :first - + def first @text = "Hello world" end - + def index self.response_body = @text end end - + class TestCallbacks1 < ActiveSupport::TestCase test "basic callbacks work" do controller = Callback1.new @@ -31,21 +31,21 @@ module AbstractController before_filter :first after_filter :second around_filter :aroundz - + def first @text = "Hello world" end - + def second @second = "Goodbye" end - + def aroundz @aroundz = "FIRST" yield @aroundz << "SECOND" end - + def index self.response_body = @text.to_s end @@ -54,7 +54,7 @@ module AbstractController class Callback2Overwrite < Callback2 before_filter :first, :except => :index end - + class TestCallbacks2 < ActiveSupport::TestCase def setup @controller = Callback2.new @@ -64,12 +64,12 @@ module AbstractController result = @controller.process(:index) assert_equal "Hello world", @controller.response_body end - + test "after_filter works" do @controller.process(:index) assert_equal "Goodbye", @controller.instance_variable_get("@second") end - + test "around_filter works" do @controller.process(:index) assert_equal "FIRSTSECOND", @controller.instance_variable_get("@aroundz") @@ -81,16 +81,16 @@ module AbstractController assert_equal "", @controller.response_body end end - + class Callback3 < ControllerWithCallbacks before_filter do |c| c.instance_variable_set("@text", "Hello world") end - + after_filter do |c| c.instance_variable_set("@second", "Goodbye") end - + def index self.response_body = @text end @@ -100,41 +100,41 @@ module AbstractController def setup @controller = Callback3.new end - + test "before_filter works with procs" do result = @controller.process(:index) assert_equal "Hello world", @controller.response_body end - + test "after_filter works with procs" do result = @controller.process(:index) assert_equal "Goodbye", @controller.instance_variable_get("@second") - end + end end - + class CallbacksWithConditions < ControllerWithCallbacks before_filter :list, :only => :index before_filter :authenticate, :except => :index - + def index self.response_body = @list.join(", ") end - + def sekrit_data self.response_body = (@list + [@authenticated]).join(", ") end - + private def list @list = ["Hello", "World"] end - + def authenticate @list = [] @authenticated = "true" end end - + class TestCallbacksWithConditions < ActiveSupport::TestCase def setup @controller = CallbacksWithConditions.new @@ -144,41 +144,41 @@ module AbstractController @controller.process(:index) assert_equal "Hello, World", @controller.response_body end - + test "when :only is specified, a before filter is not triggered on other actions" do @controller.process(:sekrit_data) assert_equal "true", @controller.response_body end - + test "when :except is specified, an after filter is not triggered on that action" do result = @controller.process(:index) assert_nil @controller.instance_variable_get("@authenticated") end end - + class CallbacksWithArrayConditions < ControllerWithCallbacks before_filter :list, :only => [:index, :listy] before_filter :authenticate, :except => [:index, :listy] - + def index self.response_body = @list.join(", ") end - + def sekrit_data self.response_body = (@list + [@authenticated]).join(", ") end - + private def list @list = ["Hello", "World"] end - + def authenticate @list = [] @authenticated = "true" - end + end end - + class TestCallbacksWithArrayConditions < ActiveSupport::TestCase def setup @controller = CallbacksWithArrayConditions.new @@ -188,54 +188,54 @@ module AbstractController result = @controller.process(:index) assert_equal "Hello, World", @controller.response_body end - + test "when :only is specified with an array, a before filter is not triggered on other actions" do result = @controller.process(:sekrit_data) assert_equal "true", @controller.response_body end - + test "when :except is specified with an array, an after filter is not triggered on that action" do result = @controller.process(:index) assert_nil @controller.instance_variable_get("@authenticated") end - end - + end + class ChangedConditions < Callback2 before_filter :first, :only => :index - + def not_index self.response_body = @text.to_s end end - + class TestCallbacksWithChangedConditions < ActiveSupport::TestCase def setup @controller = ChangedConditions.new end - + test "when a callback is modified in a child with :only, it works for the :only action" do result = @controller.process(:index) assert_equal "Hello world", @controller.response_body end - + test "when a callback is modified in a child with :only, it does not work for other actions" do result = @controller.process(:not_index) assert_equal "", @controller.response_body end end - + class SetsResponseBody < ControllerWithCallbacks before_filter :set_body - + def index self.response_body = "Fail" end - + def set_body self.response_body = "Success" end end - + class TestHalting < ActiveSupport::TestCase test "when a callback sets the response body, the action should not be invoked" do controller = SetsResponseBody.new @@ -243,6 +243,6 @@ module AbstractController assert_equal "Success", controller.response_body end end - + end end diff --git a/actionpack/test/abstract/helper_test.rb b/actionpack/test/abstract/helper_test.rb index 15c2750..7394122 100644 --- a/actionpack/test/abstract/helper_test.rb +++ b/actionpack/test/abstract/helper_test.rb @@ -4,7 +4,7 @@ ActionController::Base.helpers_path = File.expand_path('../../fixtures/helpers', module AbstractController module Testing - + class ControllerWithHelpers < AbstractController::Base include AbstractController::Rendering include Helpers @@ -13,13 +13,13 @@ module AbstractController render :inline => "Module <%= included_method %>" end end - + module HelperyTest def included_method "Included" end end - + class AbstractHelpers < ControllerWithHelpers helper(HelperyTest) do def helpery_test @@ -76,6 +76,6 @@ module AbstractController end end - + end end diff --git a/actionpack/test/abstract/translation_test.rb b/actionpack/test/abstract/translation_test.rb index 09ebfab..8ec50fd 100644 --- a/actionpack/test/abstract/translation_test.rb +++ b/actionpack/test/abstract/translation_test.rb @@ -7,19 +7,19 @@ class TranslationControllerTest < Test::Unit::TestCase def setup @controller = ActionController::Base.new end - + def test_action_controller_base_responds_to_translate assert_respond_to @controller, :translate end - + def test_action_controller_base_responds_to_t assert_respond_to @controller, :t end - + def test_action_controller_base_responds_to_localize assert_respond_to @controller, :localize end - + def test_action_controller_base_responds_to_l assert_respond_to @controller, :l end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 5be47f7..fb6961d 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -218,7 +218,7 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase end def with_autoload_path(path) - path = File.join(File.dirname(__FILE__), "fixtures", path) + path = File.join(File.dirname(__FILE__), "fixtures", path) if ActiveSupport::Dependencies.autoload_paths.include?(path) yield else diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index 4f8ad23..ef0df9d 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -257,7 +257,7 @@ class AssertSelectTest < ActionController::TestCase end assert_raise(Assertion) {assert_select_rjs :insert, :top, "test2"} end - + def test_assert_select_rjs_for_redirect_to render_rjs do |page| page.redirect_to '/' diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index ae270b7..032c22d 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -87,7 +87,7 @@ class RecordIdentifierController < ActionController::Base end class ControllerClassTests < ActiveSupport::TestCase - + def test_controller_path assert_equal 'empty', EmptyController.controller_path assert_equal EmptyController.controller_path, EmptyController.new.controller_path @@ -99,7 +99,7 @@ class ControllerClassTests < ActiveSupport::TestCase assert_equal 'empty', EmptyController.controller_name assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name end - + def test_filter_parameter_logging parameters = [] config = mock(:config => mock(:filter_parameters => parameters)) @@ -164,15 +164,15 @@ class PerformActionTest < ActionController::TestCase rescue_action_in_public! end - + def test_process_should_be_precise use_controller EmptyController exception = assert_raise AbstractController::ActionNotFound do get :non_existent end - assert_equal exception.message, "The action 'non_existent' could not be found for EmptyController" + assert_equal exception.message, "The action 'non_existent' could not be found for EmptyController" end - + def test_get_on_priv_should_show_selector use_controller MethodMissingController get :shouldnt_be_called @@ -224,7 +224,7 @@ class UrlOptionsTest < ActionController::TestCase assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') end - end + end def test_url_helpers_does_not_become_actions with_routing do |set| diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb index 7e19bce..ebe089a 100644 --- a/actionpack/test/controller/dispatcher_test.rb +++ b/actionpack/test/controller/dispatcher_test.rb @@ -6,7 +6,7 @@ class DeprecatedDispatcherTest < ActiveSupport::TestCase def call(env) [200, {}, 'response'] end - end + end def setup ActionDispatch::Callbacks.reset_callbacks(:prepare) diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index 14f1bd7..d0fd9e8 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -447,7 +447,7 @@ class FilterTest < ActionController::TestCase class ::AppSweeper < ActionController::Caching::Sweeper; end class SweeperTestController < ActionController::Base - cache_sweeper :app_sweeper + cache_sweeper :app_sweeper def show render :text => 'hello world' end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 9b96579..ad66f13 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -50,7 +50,7 @@ class HelperTest < ActiveSupport::TestCase # Set default test helper. self.test_helper = LocalAbcHelper end - + def test_deprecated_helper assert_equal expected_helper_methods, missing_methods assert_nothing_raised { @controller_class.helper TestHelper } @@ -70,25 +70,25 @@ class HelperTest < ActiveSupport::TestCase def call_controller(klass, action) request = ActionController::TestRequest.new - klass.action(action).call(request.env) + klass.action(action).call(request.env) end def test_helper_for_nested_controller - assert_equal 'hello: Iz guuut!', + assert_equal 'hello: Iz guuut!', call_controller(Fun::GamesController, "render_hello_world").last.body # request = ActionController::TestRequest.new - # + # # resp = Fun::GamesController.action(:render_hello_world).call(request.env) # assert_equal 'hello: Iz guuut!', resp.last.body end def test_helper_for_acronym_controller assert_equal "test: baz", call_controller(Fun::PdfController, "test").last.body - # + # # request = ActionController::TestRequest.new # response = ActionController::TestResponse.new # request.action = 'test' - # + # # assert_equal 'test: baz', Fun::PdfController.process(request, response).body end @@ -192,7 +192,7 @@ class IsolatedHelpersTest < ActiveSupport::TestCase def call_controller(klass, action) request = ActionController::TestRequest.new - klass.action(action).call(request.env) + klass.action(action).call(request.env) end def setup diff --git a/actionpack/test/controller/http_basic_authentication_test.rb b/actionpack/test/controller/http_basic_authentication_test.rb index 23688ca..01c650a 100644 --- a/actionpack/test/controller/http_basic_authentication_test.rb +++ b/actionpack/test/controller/http_basic_authentication_test.rb @@ -13,7 +13,7 @@ class HttpBasicAuthenticationTest < ActionController::TestCase def display render :text => 'Definitely Maybe' end - + def show render :text => 'Only for loooooong credentials' end @@ -33,7 +33,7 @@ class HttpBasicAuthenticationTest < ActionController::TestCase request_http_basic_authentication("SuperSecret") end end - + def authenticate_long_credentials authenticate_or_request_with_http_basic do |username, password| username == '1234567890123456789012345678901234567890' && password == '1234567890123456789012345678901234567890' @@ -56,7 +56,7 @@ class HttpBasicAuthenticationTest < ActionController::TestCase test "successful authentication with #{header.downcase} and long credentials" do @request.env[header] = encode_credentials('1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890') get :show - + assert_response :success assert_equal 'Only for loooooong credentials', @response.body, "Authentication failed for request header #{header} and long credentials" end diff --git a/actionpack/test/controller/http_token_authentication_test.rb b/actionpack/test/controller/http_token_authentication_test.rb index 3dfccae..3054c16 100644 --- a/actionpack/test/controller/http_token_authentication_test.rb +++ b/actionpack/test/controller/http_token_authentication_test.rb @@ -13,7 +13,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase def display render :text => 'Definitely Maybe' end - + def show render :text => 'Only for loooooong credentials' end @@ -33,7 +33,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase request_http_token_authentication("SuperSecret") end end - + def authenticate_long_credentials authenticate_or_request_with_http_token do |token, options| token == '1234567890123456789012345678901234567890' && options[:algorithm] == 'test' @@ -56,7 +56,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase test "successful authentication with #{header.downcase} and long credentials" do @request.env[header] = encode_credentials('1234567890123456789012345678901234567890', :algorithm => 'test') get :show - + assert_response :success assert_equal 'Only for loooooong credentials', @response.body, "Authentication failed for request header #{header} and long credentials" end diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 165c61f..e875174 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -115,7 +115,7 @@ end class LayoutSetInResponseTest < ActionController::TestCase include ActionView::Template::Handlers - + def test_layout_set_when_using_default_layout @controller = DefaultLayoutController.new get :hello @@ -127,7 +127,7 @@ class LayoutSetInResponseTest < ActionController::TestCase get :hello assert_template :layout => "layouts/item" end - + def test_layout_only_exception_when_included @controller = OnlyLayoutController.new get :hello diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index b5ce391..6364b71 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -36,7 +36,7 @@ class RespondToController < ActionController::Base type.all { render :text => "Nothing" } end end - + def json_xml_or_html respond_to do |type| type.json { render :text => 'JSON' } @@ -44,7 +44,7 @@ class RespondToController < ActionController::Base type.html { render :text => 'HTML' } end end - + def forced_xml request.format = :xml @@ -373,17 +373,17 @@ class RespondToControllerTest < ActionController::TestCase get :handle_any_any assert_equal 'Whatever you ask for, I got it', @response.body end - + def test_browser_check_with_any_any @request.accept = "application/json, application/xml" get :json_xml_or_html assert_equal 'JSON', @response.body - + @request.accept = "application/json, application/xml, */*" get :json_xml_or_html assert_equal 'HTML', @response.body end - + def test_rjs_type_skips_layout @request.accept = "text/javascript" diff --git a/actionpack/test/controller/new_base/etag_test.rb b/actionpack/test/controller/new_base/etag_test.rb index 51bfb22..2bca5ae 100644 --- a/actionpack/test/controller/new_base/etag_test.rb +++ b/actionpack/test/controller/new_base/etag_test.rb @@ -34,7 +34,7 @@ module Etags body = "teh Hello from without_layout.html.erb tagz" assert_body body assert_header "Etag", etag_for(body) - assert_status 200 + assert_status 200 end private diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb index 90cc793..9f69d20 100644 --- a/actionpack/test/controller/new_base/render_implicit_action_test.rb +++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb @@ -6,10 +6,10 @@ module RenderImplicitAction "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!" )] - + def hello_world() end end - + class RenderImplicitActionTest < Rack::TestCase test "render a simple action with new explicit call to render" do get "/render_implicit_action/simple/hello_world" diff --git a/actionpack/test/controller/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb index 372fb66..bb2a953 100644 --- a/actionpack/test/controller/new_base/render_layout_test.rb +++ b/actionpack/test/controller/new_base/render_layout_test.rb @@ -71,7 +71,7 @@ module ControllerLayouts self.view_paths = [ActionView::FixtureResolver.new( "layouts/application.html.erb" => "<%= yield %>", "controller_layouts/mismatch_format/index.js.rjs" => "page[:test].ext", - "controller_layouts/mismatch_format/implicit.rjs" => "page[:test].ext" + "controller_layouts/mismatch_format/implicit.rjs" => "page[:test].ext" )] def explicit diff --git a/actionpack/test/controller/new_base/render_partial_test.rb b/actionpack/test/controller/new_base/render_partial_test.rb index 1a1b36a..5c7e66d 100644 --- a/actionpack/test/controller/new_base/render_partial_test.rb +++ b/actionpack/test/controller/new_base/render_partial_test.rb @@ -1,27 +1,27 @@ require 'abstract_unit' module RenderPartial - + class BasicController < ActionController::Base - + self.view_paths = [ActionView::FixtureResolver.new( "render_partial/basic/_basic.html.erb" => "BasicPartial!", "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>" )] - + def changing @test_unchanged = 'hello' render :action => "basic" - end + end end - + class TestPartial < Rack::TestCase testing BasicController - + test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do get :changing assert_response("goodbyeBasicPartial!goodbye") end end - + end diff --git a/actionpack/test/controller/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb index d985d9f..6bd7453 100644 --- a/actionpack/test/controller/new_base/render_test.rb +++ b/actionpack/test/controller/new_base/render_test.rb @@ -65,7 +65,7 @@ module Render end end end - + class TestVariousObjectsAvailableInView < Rack::TestCase test "The request object is accessible in the view" do get "/render/blank_render/access_request" diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb index 0e6f51c..81c2a9d 100644 --- a/actionpack/test/controller/new_base/render_text_test.rb +++ b/actionpack/test/controller/new_base/render_text_test.rb @@ -3,7 +3,7 @@ require 'abstract_unit' module RenderText class SimpleController < ActionController::Base self.view_paths = [ActionView::FixtureResolver.new] - + def index render :text => "hello david" end @@ -14,24 +14,24 @@ module RenderText "layouts/application.html.erb" => "<%= yield %>, I'm here!", "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well.", "layouts/ivar.html.erb" => "<%= yield %>, <%= @ivar %>" - )] - + )] + def index render :text => "hello david" end - + def custom_code render :text => "hello world", :status => 404 end - + def with_custom_code_as_string render :text => "hello world", :status => "404 Not Found" end - + def with_nil render :text => nil end - + def with_nil_and_status render :text => nil, :status => 403 end @@ -39,23 +39,23 @@ module RenderText def with_false render :text => false end - + def with_layout_true render :text => "hello world", :layout => true end - + def with_layout_false render :text => "hello world", :layout => false end - + def with_layout_nil render :text => "hello world", :layout => nil end - + def with_custom_layout render :text => "hello world", :layout => "greetings" end - + def with_ivar_in_layout @ivar = "hello world" render :text => "hello world", :layout => "ivar" diff --git a/actionpack/test/controller/new_base/render_xml_test.rb b/actionpack/test/controller/new_base/render_xml_test.rb index d044738..b8527a9 100644 --- a/actionpack/test/controller/new_base/render_xml_test.rb +++ b/actionpack/test/controller/new_base/render_xml_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' module RenderXml - + # This has no layout and it works class BasicController < ActionController::Base self.view_paths = [ActionView::FixtureResolver.new( diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index a57a12f..258f511 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -7,7 +7,7 @@ module Fun # :ported: def hello_world end - + def nested_partial_with_form_builder render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {}, Proc.new {}) end @@ -1234,7 +1234,7 @@ class RenderTest < ActionController::TestCase assert_match(/