Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #3438: eager_loading_order_patch.diff

File eager_loading_order_patch.diff, 7.8 kB (added by josh, 1 year ago)

Patch against [6530].

  • activerecord/test/associations/eager_test.rb

    old new  
    368368    assert_equal 2, one.comments.size 
    369369  end 
    370370 
     371  def test_association_orders_work_with_eager_loading 
     372    { Author         => [ :posts,  :posts_with_comments, :posts_with_categories, :posts_with_comments_and_categories, 
     373                          :comments, :funky_comments, :special_posts, :hello_posts, :nonexistent_posts,  
     374                          :posts_with_callbacks, :posts_with_proc_callbacks, :posts_with_multiple_callbacks, 
     375                          :unchangable_posts, :author_favorites ], 
     376      Category       => [ :posts, :special_posts, :hello_posts, :nonexistent_posts ], 
     377      DependentFirm  => [ :companies ], 
     378      Firm           => [ :clients, :clients_sorted_desc, :clients_of_firm, :dependent_clients_of_firm, 
     379                          :exclusively_dependent_clients_of_firm ], 
     380      Person         => [ :readers, :posts ], 
     381      Post           => [ :comments, :special_comments, :categories, :special_categories, :readers, :people ] 
     382    }.each do |model, associations| 
     383      associations.each do |association| 
     384        regular_records = model.find(:all).sort_by(&:id) 
     385        eager_records = model.find(:all, :include => [association]).sort_by(&:id) 
     386        regular_records.size.times do |i| 
     387          assert_equal regular_records[i].send(association).map(&:id), eager_records[i].send(association).map(&:id), "#{model}.#{association} has a different order when eagerly loaded." 
     388        end 
     389 
     390        expected_order = model.find(:all, :order => "#{model.table_name}.#{model.primary_key}").map(&association).flatten.map(&:id) 
     391        actual_order = model.find(:all, :include => [association], :order => "#{model.table_name}.#{model.primary_key}").map(&association).flatten.map(&:id) 
     392        assert_equal expected_order, actual_order, "#{model}.#{association} has a different order when eagerly loaded given an :order option" 
     393      end       
     394    end 
     395  end 
     396 
    371397  def test_preconfigured_includes_with_habtm 
    372398    posts = authors(:david).posts_with_categories 
    373399    one = posts.detect { |p| p.id == 1 } 
  • activerecord/test/associations/cascaded_eager_loading_test.rb

    old new  
    104104    end 
    105105  end 
    106106 
     107  def test_association_orders_work_with_cascaded_eager_loading 
     108    [ { :posts => :comments }, { :posts => :categories }, 
     109      { :posts => [:comments, :categories] }, 
     110      { :comments => :post }, { :funky_comments => :post } ].each do |association| 
     111      regular_records = Author.find(:all).sort_by(&:id) 
     112      eager_records = Author.find(:all, :include => association).sort_by(&:id) 
     113      regular_records.size.times do |i| 
     114        assert_equal regular_records[i].send(association.keys.first).map(&:id), eager_records[i].send(association.keys.first).map(&:id), "Author.#{association.keys.first} has a different order when eagerly loaded via #{association.inspect}." 
     115      end 
     116    end 
     117  end 
     118 
    107119  def test_eager_association_loading_with_recursive_cascading_three_levels_has_many 
    108120    root_node = RecursivelyCascadedTreeMixin.find(:first, :include=>{:children=>{:children=>:children}}, :order => 'mixins.id') 
    109121    assert_equal mixins(:recursively_cascaded_tree_4), assert_no_queries { root_node.children.first.children.first.children.first } 
  • activerecord/test/fixtures/post.rb

    old new  
    1515 
    1616  has_one  :very_special_comment 
    1717  has_one  :very_special_comment_with_post, :class_name => "VerySpecialComment", :include => :post 
    18   has_many :special_comments 
     18  has_many :special_comments, :order => 'type' 
    1919 
    20   has_and_belongs_to_many :categories 
    21   has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id' 
     20  has_and_belongs_to_many :categories, :order => 'name' 
     21  has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id', :order => 'name DESC, type ASC' 
    2222 
    2323  has_many :taggings, :as => :taggable 
    2424  has_many :tags, :through => :taggings, :include => :tagging do 
     
    3838  has_many :categorizations, :foreign_key => :category_id 
    3939  has_many :authors, :through => :categorizations 
    4040 
    41   has_many :readers 
    42   has_many :people, :through => :readers 
     41  has_many :readers, :order => 'readers.person_id' 
     42  has_many :people, :through => :readers, :order => 'first_name DESC, id ASC' 
    4343 
    4444  def self.what_are_you 
    4545    'a post...' 
  • activerecord/test/fixtures/author.rb

    old new  
    11class Author < ActiveRecord::Base 
    2   has_many :posts 
    3   has_many :posts_with_comments, :include => :comments, :class_name => "Post" 
    4   has_many :posts_with_categories, :include => :categories, :class_name => "Post" 
     2  has_many :posts, :order => 'title DESC' 
     3  has_many :posts_with_comments, :include => :comments, :class_name => "Post", :order => 'title DESC' 
     4  has_many :posts_with_categories, :include => :categories, :class_name => "Post", :order => 'title' 
    55  has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post" 
    66  has_many :posts_with_extension, :class_name => "Post" do #, :extend => ProxyTestExtension 
    77    def testing_proxy_owner 
     
    1414      proxy_target 
    1515    end 
    1616  end 
    17   has_many :comments, :through => :posts 
    18   has_many :funky_comments, :through => :posts, :source => :comments 
     17  has_many :comments, :through => :posts, :order => 'body DESC' 
     18  has_many :funky_comments, :through => :posts, :source => :comments, :order => 'body' 
    1919 
    2020  has_many :special_posts 
    2121  has_many :special_post_comments, :through => :special_posts, :source => :comments 
  • activerecord/lib/active_record/associations.rb

    old new  
    12491249          add_conditions!(sql, options[:conditions], scope) 
    12501250          add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit]) 
    12511251 
     1252          # Collect all eagerly-loaded assocations with any order options, and 
     1253          # add in their table names unless it's already there. 
     1254          associated_orders = join_dependency.join_associations.select do |assoc| 
     1255            assoc.reflection.options[:order] 
     1256          end.map do |assoc| 
     1257            orders = assoc.reflection.options[:order].split(',').map(&:strip) 
     1258            orders.map do |order| 
     1259              if order =~ /\./ 
     1260                order 
     1261              else 
     1262                assoc.aliased_table_name + '.' + order 
     1263              end 
     1264            end 
     1265          end 
     1266 
     1267          # Add the association orders to the SQL statement. 
     1268          if associated_orders.any? 
     1269            if options[:order] 
     1270              sql << ", " 
     1271            else 
     1272              sql << "ORDER BY " 
     1273            end 
     1274            sql << associated_orders.flatten.join(', ') 
     1275          end 
     1276          sql << ' ' 
     1277 
    12521278          sql << "GROUP BY #{options[:group]} " if options[:group] 
    12531279  
    12541280          add_order!(sql, options[:order], scope)