Permalink
Browse files

Merge branch 'master' into async

* master: (29 commits)
  Don't test language-level exception messages
  Modity the :json_data_empty attribute from `:null => false` to `:null => true` to address ORA-01400 errors with Oracle enhanced adapter.
  Add Object#try! with the old NoMethodError raising behavior
  will now return nil instead of raise a NoMethodError if the receiving object does not implement the method
  Changelog and doc updates for the previous changes.
  Deprecate Relation#all.
  Deprecate ActiveRecord::Base.scoped.
  ActiveRecord::Base.all returns a Relation.
  Only require the `:rails_env` task where is needed.
  Modify the preference attribute from `:null => false` to `:null => true` to address ORA-01400 errors with Oracle enhanced adapter.
  * Do not convert digest auth strings to symbols. CVE-2012-3424
  fix typo in documentation
  Refactor ActiveRecord::Inheritance.base_class logic
  Missed extend for eager_autoload
  Update activerecord/CHANGELOG.md
  Switched update_column recommendation in changelog to update_columns
  Eager autoload ActiveRecord association helpers
  Use string datatype for the setting attribute to make store works all database adapters.
  remove duplicate build runs in travis.  These extra runs were used to test identity map and not fully removed when the feature was removed.
  Deprecate update_column in favor of update_columns.
  ...
  • Loading branch information...
2 parents 648e198 + c01810d commit 61e31f2c8744eccd07c23d3fad2db9ea8504909b @tenderlove tenderlove committed Jul 27, 2012
Showing with 1,242 additions and 858 deletions.
  1. +2 −2 actionpack/lib/action_controller/metal/http_authentication.rb
  2. +1 −1 actionpack/lib/action_dispatch/routing/url_for.rb
  3. +4 −4 actionpack/lib/action_view/helpers/capture_helper.rb
  4. +9 −9 actionpack/test/template/capture_helper_test.rb
  5. +1 −1 activemodel/lib/active_model/observing.rb
  6. +54 −17 activerecord/CHANGELOG.md
  7. +8 −5 activerecord/lib/active_record/associations.rb
  8. +1 −1 activerecord/lib/active_record/associations/association.rb
  9. +1 −5 activerecord/lib/active_record/associations/collection_proxy.rb
  10. +1 −1 activerecord/lib/active_record/associations/has_many_through_association.rb
  11. +1 −1 activerecord/lib/active_record/associations/has_one_association.rb
  12. +1 −1 activerecord/lib/active_record/associations/through_association.rb
  13. +1 −1 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  14. +2 −1 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  15. +15 −18 activerecord/lib/active_record/inheritance.rb
  16. +42 −19 activerecord/lib/active_record/persistence.rb
  17. +7 −7 activerecord/lib/active_record/querying.rb
  18. +12 −12 activerecord/lib/active_record/railties/databases.rake
  19. +1 −1 activerecord/lib/active_record/relation/batches.rb
  20. +1 −14 activerecord/lib/active_record/relation/finder_methods.rb
  21. +7 −7 activerecord/lib/active_record/relation/query_methods.rb
  22. +6 −13 activerecord/lib/active_record/scoping/named.rb
  23. +1 −0 activerecord/lib/active_record/validations.rb
  24. +64 −0 activerecord/lib/active_record/validations/presence.rb
  25. +1 −1 activerecord/test/cases/adapters/mysql/reserved_word_test.rb
  26. +1 −1 activerecord/test/cases/adapters/mysql2/reserved_word_test.rb
  27. +72 −0 activerecord/test/cases/adapters/postgresql/connection_test.rb
  28. +9 −9 activerecord/test/cases/associations/belongs_to_associations_test.rb
  29. +22 −22 activerecord/test/cases/associations/cascaded_eager_loading_test.rb
  30. +2 −2 activerecord/test/cases/associations/eager_load_nested_include_test.rb
  31. +7 −7 activerecord/test/cases/associations/eager_singularization_test.rb
  32. +131 −131 activerecord/test/cases/associations/eager_test.rb
  33. +1 −1 activerecord/test/cases/associations/extension_test.rb
  34. +11 −11 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  35. +46 −46 activerecord/test/cases/associations/has_many_associations_test.rb
  36. +4 −4 activerecord/test/cases/associations/has_many_through_associations_test.rb
  37. +4 −4 activerecord/test/cases/associations/has_one_associations_test.rb
  38. +15 −15 activerecord/test/cases/associations/has_one_through_associations_test.rb
  39. +4 −4 activerecord/test/cases/associations/inner_join_association_test.rb
  40. +9 −9 activerecord/test/cases/associations/inverse_associations_test.rb
  41. +35 −35 activerecord/test/cases/associations/join_model_test.rb
  42. +8 −8 activerecord/test/cases/associations_test.rb
  43. +4 −4 activerecord/test/cases/attribute_methods_test.rb
  44. +1 −1 activerecord/test/cases/autosave_association_test.rb
  45. +45 −49 activerecord/test/cases/base_test.rb
  46. +1 −1 activerecord/test/cases/batches_test.rb
  47. +16 −16 activerecord/test/cases/calculations_test.rb
  48. +1 −1 activerecord/test/cases/custom_locking_test.rb
  49. +15 −15 activerecord/test/cases/deprecated_dynamic_methods_test.rb
  50. +1 −1 activerecord/test/cases/dirty_test.rb
  51. +4 −4 activerecord/test/cases/explain_test.rb
  52. +74 −74 activerecord/test/cases/finder_test.rb
  53. +44 −14 activerecord/test/cases/inheritance_test.rb
  54. +6 −6 activerecord/test/cases/log_subscriber_test.rb
  55. +2 −2 activerecord/test/cases/migration/rename_column_test.rb
  56. +4 −4 activerecord/test/cases/modules_test.rb
  57. +30 −30 activerecord/test/cases/named_scope_test.rb
  58. +132 −20 activerecord/test/cases/persistence_test.rb
  59. +6 −6 activerecord/test/cases/readonly_test.rb
  60. +29 −29 activerecord/test/cases/relation_scoping_test.rb
  61. +77 −77 activerecord/test/cases/relations_test.rb
  62. +3 −3 activerecord/test/cases/timestamp_test.rb
  63. +44 −0 activerecord/test/cases/validations/presence_validation_test.rb
  64. +1 −1 activerecord/test/cases/validations/uniqueness_validation_test.rb
  65. +1 −1 activerecord/test/cases/xml_serialization_test.rb
  66. +2 −0 activerecord/test/config.example.yml
  67. +1 −1 activerecord/test/models/bulb.rb
  68. +3 −3 activerecord/test/models/comment.rb
  69. +4 −4 activerecord/test/models/developer.rb
  70. +4 −3 activerecord/test/models/post.rb
  71. +1 −1 activerecord/test/models/project.rb
  72. +3 −3 activerecord/test/models/topic.rb
  73. +4 −4 activerecord/test/schema/schema.rb
  74. +2 −0 activesupport/CHANGELOG.md
  75. +1 −1 activesupport/lib/active_support/callbacks.rb
  76. +17 −0 activesupport/lib/active_support/core_ext/object/try.rb
  77. +27 −3 activesupport/test/core_ext/object_and_class_ext_test.rb
  78. +1 −5 activesupport/test/ordered_hash_test.rb
  79. +0 −3 ci/travis.rb
  80. +0 −15 guides/source/active_record_querying.textile
  81. +4 −0 guides/source/active_record_validations_callbacks.textile
  82. +1 −1 railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
  83. +1 −1 railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
@@ -229,9 +229,9 @@ def decode_credentials_header(request)
end
def decode_credentials(header)
- Hash[header.to_s.gsub(/^Digest\s+/,'').split(',').map do |pair|
+ HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/,'').split(',').map do |pair|
key, value = pair.split('=', 2)
- [key.strip.to_sym, value.to_s.gsub(/^"|"$/,'').delete('\'')]
+ [key.strip, value.to_s.gsub(/^"|"$/,'').delete('\'')]
end]
end
@@ -102,7 +102,7 @@ def initialize(*)
super
end
- # Hook overriden in controller to add request information
+ # Hook overridden in controller to add request information
# with `default_url_options`. Application logic should not
# go into url_options.
def url_options
@@ -134,7 +134,7 @@ def capture(*args)
#
# <%# Add some other content, or use a different template: %>
#
- # <% content_for :navigation, true do %>
+ # <% content_for :navigation, flush: true do %>
# <li><%= link_to 'Login', :action => 'login' %></li>
# <% end %>
#
@@ -148,14 +148,14 @@ def capture(*args)
#
# WARNING: content_for is ignored in caches. So you shouldn't use it
# for elements that will be fragment cached.
- def content_for(name, content = nil, flush = false, &block)
+ def content_for(name, content = nil, options = {}, &block)
if content || block_given?
if block_given?
- flush = content if content
+ options = content if content
content = capture(&block)
end
if content
- flush ? @view_flow.set(name, content) : @view_flow.append(name, content)
+ options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content)
end
nil
else
@@ -56,7 +56,7 @@ def test_content_for_with_multiple_calls
def test_content_for_with_multiple_calls_and_flush
assert ! content_for?(:title)
content_for :title, 'foo'
- content_for :title, 'bar', true
+ content_for :title, 'bar', flush: true
assert_equal 'bar', content_for(:title)
end
@@ -75,7 +75,7 @@ def test_content_for_with_block_and_multiple_calls_with_flush
content_for :title do
'foo'
end
- content_for :title, true do
+ content_for :title, flush: true do
'bar'
end
assert_equal 'bar', content_for(:title)
@@ -86,7 +86,7 @@ def test_content_for_with_block_and_multiple_calls_with_flush_nil_content
content_for :title do
'foo'
end
- content_for :title, nil, true do
+ content_for :title, nil, flush: true do
'bar'
end
assert_equal 'bar', content_for(:title)
@@ -97,7 +97,7 @@ def test_content_for_with_block_and_multiple_calls_without_flush
content_for :title do
'foo'
end
- content_for :title, false do
+ content_for :title, flush: false do
'bar'
end
assert_equal 'foobar', content_for(:title)
@@ -117,11 +117,11 @@ def test_content_for_with_whitespace_block
def test_content_for_with_whitespace_block_and_flush
assert ! content_for?(:title)
content_for :title, 'foo'
- content_for :title, true do
+ content_for :title, flush: true do
output_buffer << " \n "
nil
end
- content_for :title, 'bar', true
+ content_for :title, 'bar', flush: true
assert_equal 'bar', content_for(:title)
end
@@ -131,9 +131,9 @@ def test_content_for_returns_nil_when_writing
assert_equal nil, content_for(:title) { output_buffer << 'bar'; nil }
assert_equal nil, content_for(:title) { output_buffer << " \n "; nil }
assert_equal 'foobar', content_for(:title)
- assert_equal nil, content_for(:title, 'foo', true)
- assert_equal nil, content_for(:title, true) { output_buffer << 'bar'; nil }
- assert_equal nil, content_for(:title, true) { output_buffer << " \n "; nil }
+ assert_equal nil, content_for(:title, 'foo', flush: true)
+ assert_equal nil, content_for(:title, flush: true) { output_buffer << 'bar'; nil }
+ assert_equal nil, content_for(:title, flush: true) { output_buffer << " \n "; nil }
assert_equal 'bar', content_for(:title)
end
@@ -215,7 +215,7 @@ def observe(*models)
# end
# end
def observed_classes
- Array(observed_class)
+ [observed_class].compact.flatten
end
# The class observed by default is inferred from the observer's class name:
@@ -1,5 +1,36 @@
## Rails 4.0.0 (unreleased) ##
+* `Model.all` now returns an `ActiveRecord::Relation`, rather than an
+ array of records. Use `Model.to_a` or `Relation#to_a` if you really
+ want an array.
+
+ In some specific cases, this may cause breakage when upgrading.
+ However in most cases the `ActiveRecord::Relation` will just act as a
+ lazy-loaded array and there will be no problems.
+
+ Note that calling `Model.all` with options (e.g.
+ `Model.all(conditions: '...')` was already deprecated, but it will
+ still return an array in order to make the transition easier.
+
+ `Model.scoped` is deprecated in favour of `Model.all`.
+
+ `Relation#all` still returns an array, but is deprecated (since it
+ would serve no purpose if we made it return a `Relation`).
+
+ *Jon Leighton*
+
+* Deprecate `update_column` method in favor of `update_columns`.
+
+ *Rafael Mendonça França*
+
+* Added an `update_columns` method. This new method updates the given attributes on an object,
+ without calling save, hence skipping validations and callbacks.
+ Example:
+
+ User.first.update_columns({:name => "sebastian", :age => 25}) # => true
+
+ *Sebastian Martinez + Rafael Mendonça França*
+
* Removed `:finder_sql` and `:counter_sql` collection association options. Please
use scopes instead.
@@ -40,11 +71,11 @@
* `ActiveRecord::Relation#inspect` now makes it clear that you are
dealing with a `Relation` object rather than an array:.
- User.where(:age => 30).inspect
- # => <ActiveRecord::Relation [#<User ...>, #<User ...>, ...]>
+ User.where(:age => 30).inspect
+ # => <ActiveRecord::Relation [#<User ...>, #<User ...>, ...]>
- User.where(:age => 30).to_a.inspect
- # => [#<User ...>, #<User ...>]
+ User.where(:age => 30).to_a.inspect
+ # => [#<User ...>, #<User ...>]
The number of records displayed will be limited to 10.
@@ -53,18 +84,25 @@
* Add `collation` and `ctype` support to PostgreSQL. These are available for PostgreSQL 8.4 or later.
Example:
- development:
- adapter: postgresql
- host: localhost
- database: rails_development
- username: foo
- password: bar
- encoding: UTF8
- collation: ja_JP.UTF8
- ctype: ja_JP.UTF8
+ development:
+ adapter: postgresql
+ host: localhost
+ database: rails_development
+ username: foo
+ password: bar
+ encoding: UTF8
+ collation: ja_JP.UTF8
+ ctype: ja_JP.UTF8
*kennyj*
+* Changed validates_presence_of on an association so that children objects
+ do not validate as being present if they are marked for destruction. This
+ prevents you from saving the parent successfully and thus putting the parent
+ in an invalid state.
+
+ *Nick Monje & Brent Wheeldon*
+
* `FinderMethods#exists?` now returns `false` with the `false` argument.
*Egor Lynko*
@@ -172,7 +210,7 @@
* Add uuid datatype support to PostgreSQL adapter. *Konstantin Shabanov*
-* `update_attribute` has been removed. Use `update_column` if
+* `update_attribute` has been removed. Use `update_columns` if
you want to bypass mass-assignment protection, validations, callbacks,
and touching of updated_at. Otherwise please use `update_attributes`.
@@ -237,13 +275,12 @@
Note that as an interim step, it is possible to rewrite the above as:
- Post.scoped(:where => { :comments_count => 10 }, :limit => 5)
+ Post.all.merge(:where => { :comments_count => 10 }, :limit => 5)
This could save you a lot of work if there is a lot of old-style
finder usage in your application.
- Calling `Post.scoped(options)` is a shortcut for
- `Post.scoped.merge(options)`. `Relation#merge` now accepts a hash of
+ `Relation#merge` now accepts a hash of
options, but they must be identical to the names of the equivalent
finder method. These are mostly identical to the old-style finder
option names, except in the following cases:
@@ -104,6 +104,7 @@ def initialize(name)
# See ActiveRecord::Associations::ClassMethods for documentation.
module Associations # :nodoc:
+ extend ActiveSupport::Autoload
extend ActiveSupport::Concern
# These classes will be loaded when associations are created.
@@ -133,11 +134,13 @@ module Builder #:nodoc:
autoload :HasAndBelongsToMany, 'active_record/associations/builder/has_and_belongs_to_many'
end
- autoload :Preloader, 'active_record/associations/preloader'
- autoload :JoinDependency, 'active_record/associations/join_dependency'
- autoload :AssociationScope, 'active_record/associations/association_scope'
- autoload :AliasTracker, 'active_record/associations/alias_tracker'
- autoload :JoinHelper, 'active_record/associations/join_helper'
+ eager_autoload do
+ autoload :Preloader, 'active_record/associations/preloader'
+ autoload :JoinDependency, 'active_record/associations/join_dependency'
+ autoload :AssociationScope, 'active_record/associations/association_scope'
+ autoload :AliasTracker, 'active_record/associations/alias_tracker'
+ autoload :JoinHelper, 'active_record/associations/join_helper'
+ end
# Clears out the association cache.
def clear_association_cache #:nodoc:
@@ -118,7 +118,7 @@ def klass
# Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
# through association's scope)
def target_scope
- klass.scoped
+ klass.all
end
# Loads the \target if needed and returns it.
@@ -896,13 +896,9 @@ def scoping
end
def spawn
- scoped
- end
-
- def scoped(options = nil)
association = @association
- super.extending! do
+ @association.scoped.extending! do
define_method(:proxy_association) { association }
end
end
@@ -171,7 +171,7 @@ def delete_through_records(records)
def find_target
return [] unless target_reflection_has_associated_record?
- scoped.all
+ scoped.to_a
end
# NOTE - not sure that we can actually cope with inverses here
@@ -36,7 +36,7 @@ def delete(method = options[:dependent])
when :destroy
target.destroy
when :nullify
- target.update_column(reflection.foreign_key, nil)
+ target.update_columns(reflection.foreign_key => nil)
end
end
end
@@ -15,7 +15,7 @@ def target_scope
scope = super
chain[1..-1].each do |reflection|
scope = scope.merge(
- reflection.klass.scoped.with_default_scope.
+ reflection.klass.all.with_default_scope.
except(:select, :create_with, :includes, :preload, :joins, :eager_load)
)
end
@@ -490,7 +490,7 @@ def structure_dump
def dump_schema_information #:nodoc:
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
- ActiveRecord::SchemaMigration.order('version').all.map { |sm|
+ ActiveRecord::SchemaMigration.order('version').map { |sm|
"INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');"
}.join "\n\n"
end
@@ -474,6 +474,7 @@ def active?
def reconnect!
clear_cache!
@connection.reset
+ @open_transactions = 0
configure_connection
end
@@ -1381,7 +1382,7 @@ def postgresql_version
UNIQUE_VIOLATION = "23505"
def translate_exception(exception, message)
- case exception.result.error_field(PGresult::PG_DIAG_SQLSTATE)
+ case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE)
when UNIQUE_VIOLATION
RecordNotUnique.new(message, exception)
when FOREIGN_KEY_VIOLATION
@@ -41,14 +41,26 @@ def symbolized_sti_name
@symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
end
- # Returns the base AR subclass that this class descends from. If A
- # extends AR::Base, A.base_class will return A. If B descends from A
+ # Returns the class descending directly from ActiveRecord::Base (or
+ # that includes ActiveRecord::Model), or an abstract class, if any, in
+ # the inheritance hierarchy.
+ #
+ # If A extends AR::Base, A.base_class will return A. If B descends from A
# through some arbitrarily deep hierarchy, B.base_class will return A.
#
# If B < A and C < B and if A is an abstract_class then both B.base_class
# and C.base_class would return B as the answer since A is an abstract_class.
def base_class
- class_of_active_record_descendant(self)
+ unless self < Model::Tag
+ raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
+ end
+
+ sup = active_record_super
+ if sup.in?([Base, Model]) || sup.abstract_class?
+ self
+ else
+ sup.base_class
+ end
end
# Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
@@ -96,21 +108,6 @@ def active_record_super #:nodoc:
protected
- # Returns the class descending directly from ActiveRecord::Base or an
- # abstract class, if any, in the inheritance hierarchy.
- def class_of_active_record_descendant(klass)
- unless klass < Model::Tag
- raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
- end
-
- sup = klass.active_record_super
- if [Base, Model].include?(klass) || [Base, Model].include?(sup) || sup.abstract_class?
- klass
- else
- class_of_active_record_descendant(sup)
- end
- end
-
# Returns the class type of the record using the current module as a prefix. So descendants of
# MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
def compute_type(type_name)
Oops, something went wrong.

0 comments on commit 61e31f2

Please sign in to comment.