提交 6f5f23aa 编写于 作者: P Pratik Naik

Add Relation#includes to be an equivalent of current finder option :include

上级 c5134715
......@@ -21,7 +21,7 @@ def initialize(owner, reflection)
construct_sql
end
delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :from, :lock, :readonly, :having, :to => :scoped
delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped
def select(select = nil, &block)
if block_given?
......
......@@ -655,7 +655,7 @@ def find(*args)
end
end
delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :from, :lock, :readonly, :having, :to => :scoped
delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped
# A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
# same arguments to this method as you can to <tt>find(:first)</tt>.
......
......@@ -5,13 +5,15 @@ class Relation
delegate :to_sql, :to => :relation
delegate :length, :collect, :map, :each, :all?, :to => :to_a
attr_reader :relation, :klass, :preload_associations, :eager_load_associations
attr_writer :readonly, :preload_associations, :eager_load_associations, :table
attr_reader :relation, :klass
attr_writer :readonly, :table
attr_accessor :preload_associations, :eager_load_associations, :include_associations
def initialize(klass, relation)
@klass, @relation = klass, relation
@preload_associations = []
@eager_load_associations = []
@include_associations = []
@loaded, @readonly = false
end
......@@ -30,7 +32,7 @@ def create!(*args, &block)
def merge(r)
raise ArgumentError, "Cannot merge a #{r.klass.name} relation with #{@klass.name} relation" if r.klass != @klass
merged_relation = spawn(table).eager_load(r.eager_load_associations).preload(r.preload_associations)
merged_relation = spawn(table).eager_load(r.eager_load_associations).preload(r.preload_associations).includes(r.include_associations)
merged_relation.readonly = r.readonly
[self.relation, r.relation].each do |arel|
......@@ -74,7 +76,9 @@ def respond_to?(method, include_private = false)
def to_a
return @records if loaded?
@records = if @eager_load_associations.any?
find_with_associations = @eager_load_associations.any?
@records = if find_with_associations
begin
@klass.send(:find_with_associations, {
:select => @relation.send(:select_clauses).join(', '),
......@@ -94,7 +98,10 @@ def to_a
@klass.find_by_sql(@relation.to_sql)
end
@preload_associations.each {|associations| @klass.send(:preload_associations, @records, associations) }
preload = @preload_associations
preload += @include_associations unless find_with_associations
preload.each {|associations| @klass.send(:preload_associations, @records, associations) }
@records.each { |record| record.readonly! } if @readonly
@loaded = true
......@@ -160,6 +167,7 @@ def spawn(relation = @relation)
relation.readonly = @readonly
relation.preload_associations = @preload_associations
relation.eager_load_associations = @eager_load_associations
relation.include_associations = @include_associations
relation.table = table
relation
end
......
......@@ -5,6 +5,10 @@ def preload(*associations)
spawn.tap {|r| r.preload_associations += Array.wrap(associations) }
end
def includes(*associations)
spawn.tap {|r| r.include_associations += Array.wrap(associations) }
end
def eager_load(*associations)
spawn.tap {|r| r.eager_load_associations += Array.wrap(associations) }
end
......
......@@ -178,7 +178,7 @@ def test_eager_association_loading_of_stis_with_multiple_references
end
end
def test_find_with_included_associations
def test_find_with_preloaded_associations
assert_queries(2) do
posts = Post.preload(:comments)
assert posts.first.comments.first
......@@ -206,6 +206,29 @@ def test_find_with_included_associations
end
end
def test_find_with_included_associations
assert_queries(2) do
posts = Post.includes(:comments)
assert posts.first.comments.first
end
assert_queries(2) do
posts = Post.scoped.includes(:comments)
assert posts.first.comments.first
end
assert_queries(2) do
posts = Post.includes(:author)
assert posts.first.author
end
assert_queries(3) do
posts = Post.includes(:author, :comments).to_a
assert posts.first.author
assert posts.first.comments.first
end
end
def test_default_scope_with_conditions_string
assert_equal Developer.find_all_by_name('David').map(&:id).sort, DeveloperCalledDavid.scoped.map(&:id).sort
assert_equal nil, DeveloperCalledDavid.create!.name
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册