mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Relation#from to accept other Relation objects
Record.from("(#{sub_query.to_sql})") -> Record.from(sub_query) Record.from("(#{sub_query.to_sql}) a") -> Record.from(sub_query, :a)
This commit is contained in:
parent
78b6fdd89f
commit
64872d1e34
5 changed files with 51 additions and 7 deletions
|
@ -1,5 +1,12 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* Added ability to ActiveRecord::Relation#from to accept other ActiveRecord::Relation objects
|
||||
|
||||
Record.from(subquery)
|
||||
Record.from(subquery, :a)
|
||||
|
||||
*Radoslav Stankov*
|
||||
|
||||
* Added custom coders support for ActiveRecord::Store. Now you can set
|
||||
your custom coder like this:
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ module ActiveRecord
|
|||
def normal_values
|
||||
Relation::SINGLE_VALUE_METHODS +
|
||||
Relation::MULTI_VALUE_METHODS -
|
||||
[:where, :order, :bind, :reverse_order, :lock, :create_with, :reordering]
|
||||
[:where, :order, :bind, :reverse_order, :lock, :create_with, :reordering, :from]
|
||||
end
|
||||
|
||||
def merge
|
||||
|
@ -76,6 +76,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def merge_single_values
|
||||
relation.from_value = values[:from] unless relation.from_value
|
||||
relation.lock_value = values[:lock] unless relation.lock_value
|
||||
relation.reverse_order_value = values[:reverse_order]
|
||||
|
||||
|
|
|
@ -300,12 +300,25 @@ module ActiveRecord
|
|||
self
|
||||
end
|
||||
|
||||
def from(value)
|
||||
spawn.from!(value)
|
||||
# Specifies table from which the records will be fetched. For example:
|
||||
#
|
||||
# Topic.select('title').from('posts')
|
||||
# #=> SELECT title FROM posts
|
||||
#
|
||||
# Can accept other relation objects. For example:
|
||||
#
|
||||
# Topic.select('title').from(Topics.approved)
|
||||
# # => SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery
|
||||
#
|
||||
# Topics.select('a.title').from(Topics.approved, :a)
|
||||
# # => SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
|
||||
#
|
||||
def from(value, subquery_name = nil)
|
||||
spawn.from!(value, subquery_name)
|
||||
end
|
||||
|
||||
def from!(value)
|
||||
self.from_value = value
|
||||
def from!(value, subquery_name = nil)
|
||||
self.from_value = [value, subquery_name]
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -415,7 +428,7 @@ module ActiveRecord
|
|||
build_select(arel, select_values.uniq)
|
||||
|
||||
arel.distinct(uniq_value)
|
||||
arel.from(from_value) if from_value
|
||||
arel.from(build_from) if from_value
|
||||
arel.lock(lock_value) if lock_value
|
||||
|
||||
arel
|
||||
|
@ -464,6 +477,17 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def build_from
|
||||
opts, name = from_value
|
||||
case opts
|
||||
when Relation
|
||||
name ||= 'subquery'
|
||||
opts.arel.as(name.to_s)
|
||||
else
|
||||
opts
|
||||
end
|
||||
end
|
||||
|
||||
def build_joins(manager, joins)
|
||||
buckets = joins.group_by do |join|
|
||||
case join
|
||||
|
|
|
@ -203,13 +203,18 @@ module ActiveRecord
|
|||
assert_equal [], relation.extending_values
|
||||
end
|
||||
|
||||
(Relation::SINGLE_VALUE_METHODS - [:lock, :reordering, :reverse_order, :create_with]).each do |method|
|
||||
(Relation::SINGLE_VALUE_METHODS - [:from, :lock, :reordering, :reverse_order, :create_with]).each do |method|
|
||||
test "##{method}!" do
|
||||
assert relation.public_send("#{method}!", :foo).equal?(relation)
|
||||
assert_equal :foo, relation.public_send("#{method}_value")
|
||||
end
|
||||
end
|
||||
|
||||
test '#from!' do
|
||||
assert relation.from!('foo').equal?(relation)
|
||||
assert_equal ['foo', nil], relation.from_value
|
||||
end
|
||||
|
||||
test '#lock!' do
|
||||
assert relation.lock!('foo').equal?(relation)
|
||||
assert_equal 'foo', relation.lock_value
|
||||
|
|
|
@ -133,6 +133,13 @@ class RelationTest < ActiveRecord::TestCase
|
|||
assert topics.loaded?
|
||||
end
|
||||
|
||||
def test_finiding_with_subquery
|
||||
relation = Topic.where(:approved => true)
|
||||
assert_equal relation.to_a, Topic.select('*').from(relation).to_a
|
||||
assert_equal relation.to_a, Topic.select('subquery.*').from(relation).to_a
|
||||
assert_equal relation.to_a, Topic.select('a.*').from(relation, :a).to_a
|
||||
end
|
||||
|
||||
def test_finding_with_conditions
|
||||
assert_equal ["David"], Author.where(:name => 'David').map(&:name)
|
||||
assert_equal ['Mary'], Author.where(["name = ?", 'Mary']).map(&:name)
|
||||
|
|
Loading…
Reference in a new issue