Changeset 4325
- Timestamp:
- 05/06/06 23:37:56 (2 years ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/associations.rb (modified) (3 diffs)
- trunk/activerecord/lib/active_record/associations/association_collection.rb (modified) (7 diffs)
- trunk/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb (modified) (2 diffs)
- trunk/activerecord/lib/active_record/associations/has_many_association.rb (modified) (1 diff)
- trunk/activerecord/lib/active_record/associations/has_many_through_association.rb (modified) (2 diffs)
- trunk/activerecord/test/associations_cascaded_eager_loading_test.rb (modified) (1 diff)
- trunk/activerecord/test/associations_join_model_test.rb (modified) (1 diff)
- trunk/activerecord/test/fixtures/author.rb (modified) (1 diff)
- trunk/activerecord/test/fixtures/categorizations.yml (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r4315 r4325 1 1 *SVN* 2 3 * Allow :uniq => true with has_many :through associations. [Jeremy Kemper] 2 4 3 5 * Ensure that StringIO is always available for the Schema dumper. [Marcel Molina Jr.] trunk/activerecord/lib/active_record/associations.rb
r4310 r4325 520 520 # inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either +:subscribers+ or 521 521 # +:subscriber+ on +Subscription+, unless a +:source+ is given. 522 # * <tt>:uniq</tt> - if set to true, duplicates will be omitted from the collection. Useful in conjunction with :through. 522 523 # 523 524 # Option examples: … … 1049 1050 :select, :conditions, :include, :order, :group, :limit, :offset, 1050 1051 :as, :through, :source, 1052 :uniq, 1051 1053 :finder_sql, :counter_sql, 1052 1054 :before_add, :after_add, :before_remove, :after_remove, … … 1086 1088 :class_name, :table_name, :join_table, :foreign_key, :association_foreign_key, 1087 1089 :select, :conditions, :include, :order, :group, :limit, :offset, 1088 :finder_sql, :delete_sql, :insert_sql, :uniq, 1090 :uniq, 1091 :finder_sql, :delete_sql, :insert_sql, 1089 1092 :before_add, :after_add, :before_remove, :after_remove, 1090 1093 :extend trunk/activerecord/lib/active_record/associations/association_collection.rb
r4144 r4325 10 10 11 11 def reset 12 @target = []12 reset_target! 13 13 @loaded = false 14 14 end … … 29 29 end 30 30 end 31 31 32 32 result && self 33 33 end … … 40 40 load_target 41 41 delete(@target) 42 @target = []42 reset_target! 43 43 end 44 44 … … 78 78 end 79 79 80 @target = []80 reset_target! 81 81 end 82 82 83 83 def create(attributes = {}) 84 84 # Can't use Base.create since the foreign key may be a protected attribute. … … 96 96 # and you need to fetch that collection afterwards, it'll take one less SELECT query if you use length. 97 97 def size 98 if loaded? then @target.size else count_records end98 if loaded? && !@reflection.options[:uniq] then @target.size else count_records end 99 99 end 100 100 101 101 # Returns the size of the collection by loading it and calling size on the array. If you want to use this method to check 102 102 # whether the collection is empty, use collection.length.zero? instead of collection.empty? … … 104 104 load_target.size 105 105 end 106 106 107 107 def empty? 108 108 size.zero? 109 109 end 110 110 111 111 def uniq(collection = self) 112 collection. inject([]) { |uniq_records, record| uniq_records << record unless uniq_records.include?(record); uniq_records }112 collection.to_set.to_a 113 113 end 114 114 … … 127 127 end 128 128 end 129 130 protected 131 def reset_target! 132 @target = Array.new 133 end 134 135 def find_target 136 records = 137 if @reflection.options[:finder_sql] 138 @reflection.klass.find_by_sql(@finder_sql) 139 else 140 find(:all) 141 end 142 143 @reflection.options[:uniq] ? uniq(records) : records 144 end 129 145 130 146 private trunk/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
r4123 r4325 69 69 self 70 70 end 71 71 72 72 alias :concat_with_attributes :push_with_attributes 73 73 74 def size75 @reflection.options[:uniq] ? count_records : super76 end77 78 74 protected 79 75 def method_missing(method, *args, &block) … … 86 82 end 87 83 end 88 89 def find_target 90 if @reflection.options[:finder_sql] 91 records = @reflection.klass.find_by_sql(@finder_sql) 92 else 93 records = find(:all) 94 end 95 96 @reflection.options[:uniq] ? uniq(records) : records 97 end 98 84 99 85 def count_records 100 86 load_target.size trunk/activerecord/lib/active_record/associations/has_many_association.rb
r4237 r4325 107 107 end 108 108 end 109 110 def find_target111 if @reflection.options[:finder_sql]112 @reflection.klass.find_by_sql(@finder_sql)113 else114 find(:all)115 end116 end117 109 118 110 def count_records trunk/activerecord/lib/active_record/associations/has_many_through_association.rb
r4265 r4325 57 57 end 58 58 end 59 59 60 60 def find_target 61 @reflection.klass.find(:all,61 records = @reflection.klass.find(:all, 62 62 :select => construct_select, 63 63 :conditions => construct_conditions, … … 69 69 :include => @reflection.options[:include] || @reflection.source_reflection.options[:include] 70 70 ) 71 72 @reflection.options[:uniq] ? records.to_set.to_a : records 71 73 end 72 74 trunk/activerecord/test/associations_cascaded_eager_loading_test.rb
r4022 r4325 29 29 assert_equal 9, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i} 30 30 assert_equal 1, authors[0].categorizations.size 31 assert_equal 1, authors[1].categorizations.size31 assert_equal 2, authors[1].categorizations.size 32 32 end 33 33 trunk/activerecord/test/associations_join_model_test.rb
r4265 r4325 13 13 14 14 def test_has_many 15 assert _equal categories(:general), authors(:david).categories.first16 end 17 15 assert authors(:david).categories.include?(categories(:general)) 16 end 17 18 18 def test_has_many_inherited 19 assert _equal categories(:sti_test), authors(:mary).categories.first19 assert authors(:mary).categories.include?(categories(:sti_test)) 20 20 end 21 21 22 22 def test_inherited_has_many 23 assert_equal authors(:mary), categories(:sti_test).authors.first 24 end 25 23 assert categories(:sti_test).authors.include?(authors(:mary)) 24 end 25 26 def test_has_many_uniq_through_join_model 27 assert_equal 2, authors(:mary).categorized_posts.size 28 assert_equal 1, authors(:mary).unique_categorized_posts.size 29 end 30 26 31 def test_polymorphic_has_many 27 assert _equal taggings(:welcome_general), posts(:welcome).taggings.first28 end 29 32 assert posts(:welcome).taggings.include?(taggings(:welcome_general)) 33 end 34 30 35 def test_polymorphic_has_one 31 36 assert_equal taggings(:welcome_general), posts(:welcome).tagging trunk/activerecord/test/fixtures/author.rb
r4169 r4325 26 26 has_many :categorizations 27 27 has_many :categories, :through => :categorizations 28 29 has_many :categorized_posts, :through => :categorizations, :source => :post 30 has_many :unique_categorized_posts, :through => :categorizations, :source => :post, :uniq => true 28 31 29 32 has_many :nothings, :through => :kateggorisatons, :class_name => 'Category' trunk/activerecord/test/fixtures/categorizations.yml
r3315 r4325 4 4 post_id: 1 5 5 category_id: 1 6 6 7 7 mary_thinking_sti: 8 8 id: 2 … … 10 10 post_id: 2 11 11 category_id: 3 12 13 mary_thinking_general: 14 id: 3 15 author_id: 2 16 post_id: 2 17 category_id: 1