aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activemodel/lib/active_model/validations.rb4
-rw-r--r--activemodel/test/cases/validations_test.rb2
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb36
-rw-r--r--activerecord/test/cases/calculations_test.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/string.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/string/interpolation.rb2
-rw-r--r--guides/source/active_support_core_extensions.textile14
8 files changed, 43 insertions, 30 deletions
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 72176e9bdd..611e9ffd55 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -177,12 +177,12 @@ module ActiveModel
super
end
end
-
+
# Clean the +Errors+ object if instance is duped
def initialize_dup(other) # :nodoc:
@errors = nil
super
- end
+ end
# Returns the +Errors+ object that holds all information about attribute error messages.
def errors
diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb
index f9bb877316..1f5023bf76 100644
--- a/activemodel/test/cases/validations_test.rb
+++ b/activemodel/test/cases/validations_test.rb
@@ -344,7 +344,7 @@ class ValidationsTest < ActiveModel::TestCase
Topic.validates :title, options
assert_equal({ :presence => true }, options)
end
-
+
def test_dup_validity_is_independent
Topic.validates_presence_of :title
topic = Topic.new("title" => "Litterature")
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index e53d688ad9..3328f80fdd 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -4006,7 +4006,7 @@
* Fixed that adding a record to a has_and_belongs_to collection would always save it -- now it only saves if its a new record #1203 *Alisdair McDiarmid*
-* Fixed saving of in-memory association structures to happen as a after_create/after_update callback instead of after_save -- that way you can add new associations in after_create/after_update callbacks without getting them saved twice
+* Fixed saving of in-memory association structures to happen as an after_create/after_update callback instead of after_save -- that way you can add new associations in after_create/after_update callbacks without getting them saved twice
* Allow any Enumerable, not just Array, to work as bind variables #1344 *Jeremy Kemper*
@@ -5519,7 +5519,7 @@
* Fixed that adding a record to a has_and_belongs_to collection would always save it -- now it only saves if its a new record #1203 *Alisdair McDiarmid*
-* Fixed saving of in-memory association structures to happen as a after_create/after_update callback instead of after_save -- that way you can add new associations in after_create/after_update callbacks without getting them saved twice
+* Fixed saving of in-memory association structures to happen as an after_create/after_update callback instead of after_save -- that way you can add new associations in after_create/after_update callbacks without getting them saved twice
* Allow any Enumerable, not just Array, to work as bind variables #1344 *Jeremy Kemper*
@@ -6441,7 +6441,7 @@
post.categories.push_with_attributes(category, :added_on => Date.today)
post.categories.first.added_on # => Date.today
- NOTE: The categories table doesn't have a added_on column, it's the categories_post join table that does!
+ NOTE: The categories table doesn't have an added_on column, it's the categories_post join table that does!
* Fixed that :exclusively_dependent and :dependent can't be activated at the same time on has_many associations *Jeremy Kemper*
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 3ce9995031..aa2f325f74 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -108,15 +108,36 @@ module ActiveRecord
0
end
- # This method is designed to perform select by a single column as direct SQL query
- # Returns <tt>Array</tt> with values of the specified column name
- # The values has same data type as column.
+ # Use <tt>pluck</tt> as a shortcut to select a single attribute without
+ # loading a bunch of records just to grab one attribute you want.
+ #
+ # Person.pluck(:name)
+ #
+ # instead of
+ #
+ # Person.all.map(&:name)
+ #
+ # Pluck returns an <tt>Array</tt> of attribute values type-casted to match
+ # the plucked column name, if it can be deduced. Plucking a SQL fragment
+ # returns String values by default.
#
# Examples:
#
- # Person.pluck(:id) # SELECT people.id FROM people
- # Person.uniq.pluck(:role) # SELECT DISTINCT role FROM people
- # Person.where(:age => 21).limit(5).pluck(:id) # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
+ # Person.pluck(:id)
+ # # SELECT people.id FROM people
+ # # => [1, 2, 3]
+ #
+ # Person.uniq.pluck(:role)
+ # # SELECT DISTINCT role FROM people
+ # # => ['admin', 'member', 'guest']
+ #
+ # Person.where(:age => 21).limit(5).pluck(:id)
+ # # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
+ # # => [2, 3]
+ #
+ # Person.pluck('DATEDIFF(updated_at, created_at)')
+ # # SELECT DATEDIFF(updated_at, created_at) FROM people
+ # # => ['0', '27761', '173']
#
def pluck(column_name)
key = column_name.to_s.split('.', 2).last
@@ -130,7 +151,8 @@ module ActiveRecord
column = types[key]
result.map do |attributes|
- value = klass.initialize_attributes(attributes)[key]
+ raise ArgumentError, "Pluck expects to select just one attribute: #{attributes.inspect}" unless attributes.one?
+ value = klass.initialize_attributes(attributes).first[1]
if column
column.type_cast value
else
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index e096585f62..c9a70bae77 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -466,6 +466,14 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal [7], Company.joins(:contracts).pluck(:developer_id)
end
+ def test_pluck_with_selection_clause
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT credit_limit').sort
+ end
+
+ def test_pluck_expects_a_single_selection
+ assert_raise(ArgumentError) { Account.pluck 'id, credit_limit' }
+ end
+
def test_plucks_with_ids
assert_equal Company.all.map(&:id).sort, Company.ids.sort
end
diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb
index ab49af55bf..fb36262528 100644
--- a/activesupport/lib/active_support/core_ext/string.rb
+++ b/activesupport/lib/active_support/core_ext/string.rb
@@ -6,7 +6,6 @@ require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/string/access'
require 'active_support/core_ext/string/xchar'
require 'active_support/core_ext/string/behavior'
-require 'active_support/core_ext/string/interpolation'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/string/exclude'
require 'active_support/core_ext/string/strip'
diff --git a/activesupport/lib/active_support/core_ext/string/interpolation.rb b/activesupport/lib/active_support/core_ext/string/interpolation.rb
deleted file mode 100644
index 7f764e9de1..0000000000
--- a/activesupport/lib/active_support/core_ext/string/interpolation.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require 'active_support/i18n'
-require 'i18n/core_ext/string/interpolate'
diff --git a/guides/source/active_support_core_extensions.textile b/guides/source/active_support_core_extensions.textile
index bf30ed64c8..afd43ab317 100644
--- a/guides/source/active_support_core_extensions.textile
+++ b/guides/source/active_support_core_extensions.textile
@@ -1277,20 +1277,6 @@ The <tt>inquiry</tt> method converts a string into a +StringInquirer+ object mak
"active".inquiry.inactive? # => false
</ruby>
-h4. Key-based Interpolation
-
-In Ruby 1.9 the <tt>%</tt> string operator supports key-based interpolation, both formatted and unformatted:
-
-<ruby>
-"Total is %<total>.02f" % {:total => 43.1} # => Total is 43.10
-"I say %{foo}" % {:foo => "wadus"} # => "I say wadus"
-"I say %{woo}" % {:foo => "wadus"} # => KeyError
-</ruby>
-
-Active Support adds that functionality to <tt>%</tt> in previous versions of Ruby.
-
-NOTE: Defined in +active_support/core_ext/string/interpolation.rb+.
-
h4. +starts_with?+ and +ends_with?+
Active Support defines 3rd person aliases of +String#start_with?+ and +String#end_with?+: