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

Ticket #9640: fix_nested_include_with_mixed_record_type.patch

File fix_nested_include_with_mixed_record_type.patch, 5.1 kB (added by acechase, 3 months ago)
  • activerecord/test/cases/associations/eager_load_nested_include_test.rb

    old new  
     1require File.dirname(__FILE__) + '/../test_helper' 
     2 
     3class EagerLoadPolyAssocsTest < Test::Unit::TestCase 
     4  OPTS = { :options => "Engine=MyISAM" } 
     5  NUM_SIMPLE_OBJS = 50 
     6  NUM_SHAPE_EXPRESSIONS = 100 
     7 
     8  def setup 
     9    unless ShapeExpression.table_exists? 
     10      silence_stream(STDOUT) { create_test_tables }  
     11      generate_test_object_graphs 
     12    end 
     13  end 
     14 
     15  def create_test_tables 
     16    mig = ActiveRecord::Migration 
     17    [:circles, :squares, :triangles, :non_poly_ones, :non_poly_twos].each do |t| 
     18      mig.create_table t, OPTS do  end 
     19    end 
     20 
     21    mig.create_table :shape_expressions, OPTS do 
     22      string  :paint_type 
     23      integer :paint_id 
     24      string  :shape_type 
     25      integer :shape_id 
     26    end 
     27    mig.create_table :paint_colors, OPTS do 
     28      integer :non_poly_one_id 
     29    end 
     30    mig.create_table :paint_textures, OPTS do 
     31      integer :non_poly_two_id 
     32    end 
     33  end 
     34 
     35  def teardown 
     36    drop_tables 
     37  end 
     38   
     39  def drop_tables 
     40    ShapeExpression.connection.reconnect! 
     41    silence_stream(STDOUT) do 
     42      mig = ActiveRecord::Migration 
     43      [:circles, :squares, :triangles, :paint_colors, :paint_textures, 
     44       :shape_expressions, :non_poly_ones, :non_poly_twos].each do |t| 
     45        mig.drop_table t 
     46      end 
     47    end 
     48  end 
     49    
     50  # meant to be supplied as an ID, never returns 0 
     51  def rand_simple 
     52    val = (NUM_SIMPLE_OBJS * rand).round 
     53    val == 0 ? 1 : val 
     54  end 
     55 
     56  def generate_test_object_graphs 
     57    1.upto(NUM_SIMPLE_OBJS) do 
     58      [Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!) 
     59    end 
     60    1.upto(NUM_SIMPLE_OBJS) do |i| 
     61      PaintColor.create!(:non_poly_one_id => rand_simple) 
     62      PaintTexture.create!(:non_poly_two_id => rand_simple) 
     63    end 
     64    1.upto(NUM_SHAPE_EXPRESSIONS) do |i| 
     65      ShapeExpression.create!(:shape_type => [Circle, Square, Triangle].rand.to_s, :shape_id => rand_simple, 
     66                              :paint_type => [PaintColor, PaintTexture].rand.to_s, :paint_id => rand_simple) 
     67    end 
     68  end 
     69 
     70  def test_include_query 
     71    res = 0 
     72    res = ShapeExpression.find :all, :include => [ :shape, { :paint => :non_poly } ] 
     73    assert_equal NUM_SHAPE_EXPRESSIONS, res.size 
     74    ShapeExpression.connection.disconnect! 
     75    assert_nothing_raised "confirm we can access associations in memory" do  
     76      res.each do |se|  
     77        assert_not_nil se.paint.non_poly, "this is the association that was loading incorrectly before the change" 
     78        assert_not_nil se.shape, "just making sure other associations still work" 
     79      end 
     80    end   
     81    assert_raise ActiveRecord::StatementInvalid, "An exception should be raised when db connectivity is required" do 
     82      res[0].reload 
     83    end 
     84  end 
     85end 
     86 
     87class ShapeExpression < ActiveRecord::Base 
     88  belongs_to :shape, :polymorphic => true 
     89  belongs_to :paint, :polymorphic => true 
     90end 
     91 
     92class Circle < ActiveRecord::Base 
     93  has_many :shape_expressions, :as => :shape 
     94end 
     95class Square < ActiveRecord::Base 
     96  has_many :shape_expressions, :as => :shape 
     97end 
     98class Triangle < ActiveRecord::Base 
     99  has_many :shape_expressions, :as => :shape 
     100end 
     101class PaintColor  < ActiveRecord::Base 
     102  has_many   :shape_expressions, :as => :paint 
     103  belongs_to :non_poly, :foreign_key => "non_poly_one_id", :class_name => "NonPolyOne" 
     104end 
     105class PaintTexture < ActiveRecord::Base 
     106  has_many   :shape_expressions, :as => :paint 
     107  belongs_to :non_poly, :foreign_key => "non_poly_two_id", :class_name => "NonPolyTwo" 
     108end 
     109class NonPolyOne < ActiveRecord::Base 
     110  has_many :paint_colors 
     111end 
     112class NonPolyTwo < ActiveRecord::Base 
     113  has_many :paint_textures 
     114end 
  • activerecord/lib/active_record/association_preload.rb

    old new  
    3333      def preload_one_association(records, association, preload_options={}) 
    3434        reflection = reflections[association] 
    3535        raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection 
    36  
     36        # class uniformity is not guaranteed for objects in records array, separate by class before querying 
     37        records_by_class = Hash.new { |hash, key| hash[key] = [] } 
     38        records.each do |record| 
     39          records_by_class[record.class] << record 
     40        end 
     41        records_by_class.each_pair do |klass, records| 
     42          reflection = klass.reflections[association] 
    3743        send(:"preload_#{reflection.macro}_association", records, reflection, preload_options) 
    3844      end 
     45      end 
    3946 
    4047      def add_preloaded_records_to_collection(parent_records, reflection_name, associated_record) 
    4148        parent_records.each do |parent_record|