Fix regression caused due to removal of select method from CollectionAssociation

- CollectionAssociation#select was removed in
  https://github.com/rails/rails/pull/25989 in favor of
  QueryMethods#select but it caused a regression when passing arguments
  to select and a block.
- This used to work earlier in Rails 4.2 and Rails 5. See gist
  https://gist.github.com/prathamesh-sonpatki/a7df922273473a77dfbc742a4be4b618.
- This commit restores the behavior of Rails 4.2 and Rails 5.0.0 to
  allow passing arguments and block at the same time but also deprecates
  it.
- Because, these arguments do not have any effect on the output of
  select when select is used with a block.
- Updated documentation to remove the example passing arguments and
  block at the same time to `CollectionProxy#select`.
This commit is contained in:
Prathamesh Sonpatki 2016-09-07 11:35:01 +05:30
parent 7bbd3e68ed
commit 56bfaf7f03
No known key found for this signature in database
GPG Key ID: 8B90F6B89E2BCB71
4 changed files with 22 additions and 7 deletions

@ -1,3 +1,8 @@
* Deprecate passing arguments and block at the same time to
`ActiveRecord::QueryMethods#select`.
*Prathamesh Sonpatki*
* Optimistic locking: Added ability update locking_column value.
Ignore optimistic locking if update with new locking_column value.

@ -106,12 +106,6 @@ def loaded?
# # #<Pet id: 2, name: "Spook", person_id: 1>,
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# # ]
#
# person.pets.select(:name) { |pet| pet.name =~ /oo/ }
# # => [
# # #<Pet id: 2, name: "Spook">,
# # #<Pet id: 3, name: "Choo-Choo">
# # ]
# Finds an object in the collection responding to the +id+. Uses the same
# rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound

@ -242,7 +242,16 @@ def references!(*table_names) # :nodoc:
# Model.select(:field).first.other_field
# # => ActiveModel::MissingAttributeError: missing attribute: other_field
def select(*fields)
return super if block_given?
if block_given?
if fields.any?
ActiveSupport::Deprecation.warn(<<-WARNING.squish)
When select is called with a block, it ignores other arguments. This behavior is now deprecated and will result in an ArgumentError in Rails 5.1. You can safely remove the arguments to resolve the deprecation warning because they do not have any effect on the output of the call to the select method with a block.
WARNING
end
return super()
end
raise ArgumentError, "Call this with at least one field" if fields.empty?
spawn._select!(*fields)
end

@ -788,6 +788,13 @@ def test_select_with_block
assert_equal [1], posts(:welcome).comments.select { |c| c.id == 1 }.map(&:id)
end
def test_select_with_block_and_specific_attributes
assert_deprecated do
comments = posts(:welcome).comments.select(:id, :body) { |c| c.id == 1 }
assert_equal [1], comments.map(&:id)
end
end
def test_select_without_foreign_key
assert_equal companies(:first_firm).accounts.first.credit_limit, companies(:first_firm).accounts.select(:credit_limit).first.credit_limit
end