Skip to content

Commit

Permalink
Handle aliased attributes in AR::Relation#select, #order, etc.
Browse files Browse the repository at this point in the history
With this we can write `Model#select(:aliased)`, `Model#order(:aliased)`,
`Model#reoder(aliased: :desc)`, etc.

Supplementary work to 5412206.
  • Loading branch information
kuroda committed Jan 29, 2014
1 parent b9cd5a2 commit c1d9934
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
4 changes: 4 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
* Handle aliased attributes `select()`, `order()` and `reorder()`.

*Tsutomu Kuroda*

* Reset the collection association when calling `reset` on it.

Before:
Expand Down
6 changes: 5 additions & 1 deletion activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -234,7 +234,9 @@ def select(*fields)

def select!(*fields) # :nodoc:
fields.flatten!

fields.map! do |field|
klass.attribute_alias?(field) ? klass.attribute_alias(field).to_sym : field
end
self.select_values += fields
self
end
Expand Down Expand Up @@ -1048,9 +1050,11 @@ def preprocess_order_args(order_args)
order_args.map! do |arg|
case arg
when Symbol
arg = klass.attribute_alias(arg).to_sym if klass.attribute_alias?(arg)
table[arg].asc
when Hash
arg.map { |field, dir|
field = klass.attribute_alias(field).to_sym if klass.attribute_alias?(field)
table[field].send(dir)
}
else
Expand Down
4 changes: 4 additions & 0 deletions activerecord/test/cases/relation/mutation_test.rb
Expand Up @@ -14,6 +14,10 @@ def connection
def relation_delegate_class(klass)
self.class.relation_delegate_class(klass)
end

def attribute_alias?(name)
false
end
end

def relation
Expand Down
31 changes: 31 additions & 0 deletions activerecord/test/cases/relations_test.rb
Expand Up @@ -206,12 +206,36 @@ def test_finding_with_order_concatenated
assert_equal topics(:fourth).title, topics.first.title
end

def test_finding_with_order_by_aliased_attributes
topics = Topic.order(:heading)
assert_equal 5, topics.to_a.size
assert_equal topics(:fifth).title, topics.first.title
end

def test_finding_with_assoc_order_by_aliased_attributes
topics = Topic.order(heading: :desc)
assert_equal 5, topics.to_a.size
assert_equal topics(:third).title, topics.first.title
end

def test_finding_with_reorder
topics = Topic.order('author_name').order('title').reorder('id').to_a
topics_titles = topics.map{ |t| t.title }
assert_equal ['The First Topic', 'The Second Topic of the day', 'The Third Topic of the day', 'The Fourth Topic of the day', 'The Fifth Topic of the day'], topics_titles
end

def test_finding_with_reorder_by_aliased_attributes
topics = Topic.order('author_name').reorder(:heading)
assert_equal 5, topics.to_a.size
assert_equal topics(:fifth).title, topics.first.title
end

def test_finding_with_assoc_reorder_by_aliased_attributes
topics = Topic.order('author_name').reorder(heading: :desc)
assert_equal 5, topics.to_a.size
assert_equal topics(:third).title, topics.first.title
end

def test_finding_with_order_and_take
entrants = Entrant.order("id ASC").limit(2).to_a

Expand Down Expand Up @@ -775,6 +799,13 @@ def test_select_takes_a_variable_list_of_args
assert_equal david.salary, developer.salary
end

def test_select_takes_an_aliased_attribute
first = topics(:first)

topic = Topic.where(id: first.id).select(:heading).first
assert_equal first.heading, topic.heading
end

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

0 comments on commit c1d9934

Please sign in to comment.