Skip to content

Commit

Permalink
Model.select takes a variable list of arguments.
Browse files Browse the repository at this point in the history
This is a cleaner version of #6916.

Closes #3165.
  • Loading branch information
isaacsanders authored and Francesco Rodriguez committed Aug 23, 2012
1 parent 764deab commit 7bf9db5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
23 changes: 12 additions & 11 deletions activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -136,34 +136,35 @@ def references!(*args)
# Second: Modifies the SELECT statement for the query so that only certain # Second: Modifies the SELECT statement for the query so that only certain
# fields are retrieved: # fields are retrieved:
# #
# >> Model.select(:field) # Model.select(:field)
# => [#<Model field:value>] # # => [#<Model field:value>]
# #
# Although in the above example it looks as though this method returns an # Although in the above example it looks as though this method returns an
# array, it actually returns a relation object and can have other query # array, it actually returns a relation object and can have other query
# methods appended to it, such as the other methods in ActiveRecord::QueryMethods. # methods appended to it, such as the other methods in ActiveRecord::QueryMethods.
# #
# The argument to the method can also be an array of fields. # The argument to the method can also be an array of fields.
# #
# >> Model.select([:field, :other_field, :and_one_more]) # Model.select(:field, :other_field, :and_one_more)
# => [#<Model field: "value", other_field: "value", and_one_more: "value">] # # => [#<Model field: "value", other_field: "value", and_one_more: "value">]
# #
# Accessing attributes of an object that do not have fields retrieved by a select # Accessing attributes of an object that do not have fields retrieved by a select
# will throw <tt>ActiveModel::MissingAttributeError</tt>: # will throw <tt>ActiveModel::MissingAttributeError</tt>:
# #
# >> Model.select(:field).first.other_field # Model.select(:field).first.other_field
# => ActiveModel::MissingAttributeError: missing attribute: other_field # # => ActiveModel::MissingAttributeError: missing attribute: other_field
def select(value = Proc.new) def select(*fields)
if block_given? if block_given?
to_a.select { |*block_args| value.call(*block_args) } to_a.select { |*block_args| yield(*block_args) }
else else
spawn.select!(value) raise ArgumentError, 'Call this with at least one field' if fields.empty?
spawn.select!(*fields)
end end
end end


# Like #select, but modifies relation in place. # Like #select, but modifies relation in place.
def select!(value) def select!(*fields)
self.select_values += Array.wrap(value) self.select_values += fields.flatten
self self
end end


Expand Down
8 changes: 8 additions & 0 deletions activerecord/test/cases/relations_test.rb
Expand Up @@ -656,6 +656,14 @@ def test_delete_all_limit_error
assert_raises(ActiveRecord::ActiveRecordError) { Author.limit(10).delete_all } assert_raises(ActiveRecord::ActiveRecordError) { Author.limit(10).delete_all }
end end


def test_select_takes_a_variable_list_of_args
david = developers(:david)

developer = Developer.where(id: david.id).select(:name, :salary).first
assert_equal david.name, developer.name
assert_equal david.salary, developer.salary
end

def test_select_argument_error def test_select_argument_error
assert_raises(ArgumentError) { Developer.select } assert_raises(ArgumentError) { Developer.select }
end end
Expand Down

0 comments on commit 7bf9db5

Please sign in to comment.