Skip to content

Commit

Permalink
Merge branch 'master' into async
Browse files Browse the repository at this point in the history
* 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
tenderlove committed Jul 27, 2012
2 parents 648e198 + c01810d commit 61e31f2
Show file tree
Hide file tree
Showing 83 changed files with 1,242 additions and 858 deletions.
4 changes: 2 additions & 2 deletions actionpack/lib/action_controller/metal/http_authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/routing/url_for.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions actionpack/lib/action_view/helpers/capture_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 %>
#
Expand All @@ -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
Expand Down
18 changes: 9 additions & 9 deletions actionpack/test/template/capture_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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

Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion activemodel/lib/active_model/observing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
71 changes: 54 additions & 17 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -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.

Expand All @@ -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*
Expand Down Expand Up @@ -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`.

Expand Down Expand Up @@ -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:
Expand Down
13 changes: 8 additions & 5 deletions activerecord/lib/active_record/associations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion activerecord/lib/active_record/associations/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ def active?
def reconnect!
clear_cache!
@connection.reset
@open_transactions = 0
configure_connection
end

Expand Down Expand Up @@ -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
Expand Down
33 changes: 15 additions & 18 deletions activerecord/lib/active_record/inheritance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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>).
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 61e31f2

Please sign in to comment.