Changeset 5660
- Timestamp:
- 12/01/06 21:24:47 (2 years ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/base.rb (modified) (4 diffs)
- trunk/activerecord/test/base_test.rb (modified) (4 diffs)
- trunk/activerecord/test/fixtures/db_definitions/mysql.sql (modified) (3 diffs)
- trunk/activerecord/test/fixtures/db_definitions/sqlite.sql (modified) (2 diffs)
- trunk/activerecord/test/fixtures/post.rb (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r5604 r5660 1 1 *SVN* 2 3 * Subclasses of an abstract class work with single-table inheritance. #5704 [nick+rails@ag.arizona.edu, Ryan Davis, Jeremy Kemper] 2 4 3 5 * Change fixture_path to a class inheritable accessor allowing test cases to have their own custom set of fixtures. #6672 [zdennis] trunk/activerecord/lib/active_record/base.rb
r5593 r5660 817 817 818 818 def descends_from_active_record? # :nodoc: 819 superclass == Base|| !columns_hash.include?(inheritance_column)819 superclass.abstract_class? || !columns_hash.include?(inheritance_column) 820 820 end 821 821 … … 1162 1162 segments << sanitize_sql(scope[:conditions]) if scope && scope[:conditions] 1163 1163 segments << sanitize_sql(conditions) unless conditions.nil? 1164 segments << type_condition unless descends_from_active_record? 1164 segments << type_condition unless descends_from_active_record? 1165 1165 segments.compact! 1166 1166 sql << "WHERE (#{segments.join(") AND (")}) " unless segments.empty? … … 1363 1363 # Returns the class descending directly from ActiveRecord in the inheritance hierarchy. 1364 1364 def class_of_active_record_descendant(klass) 1365 if klass.superclass == Base || klass.superclass.abstract_class?1365 if klass.superclass.abstract_class? 1366 1366 klass 1367 1367 elsif klass.superclass.nil? … … 1483 1483 end 1484 1484 end 1485 1486 # ActiveRecord::Base is abstract. 1487 self.abstract_class = true 1485 1488 1486 1489 public trunk/activerecord/test/base_test.rb
r5597 r5660 11 11 require 'fixtures/subscriber' 12 12 require 'fixtures/keyboard' 13 require 'fixtures/post' 13 14 14 15 class Category < ActiveRecord::Base; end … … 29 30 30 31 class LoosePerson < ActiveRecord::Base 32 self.table_name = 'people' 33 self.abstract_class = true 31 34 attr_protected :credit_rating, :administrator 32 self.abstract_class = true33 35 end 34 36 … … 38 40 39 41 class TightPerson < ActiveRecord::Base 42 self.table_name = 'people' 40 43 attr_accessible :name, :address 41 44 end … … 1362 1365 end 1363 1366 1364 def test_base_class 1367 def test_abstract_class 1368 assert ActiveRecord::Base.abstract_class? 1365 1369 assert LoosePerson.abstract_class? 1366 1370 assert !LooseDescendant.abstract_class? 1371 end 1372 1373 def test_base_class 1367 1374 assert_equal LoosePerson, LoosePerson.base_class 1368 1375 assert_equal LooseDescendant, LooseDescendant.base_class 1369 1376 assert_equal TightPerson, TightPerson.base_class 1370 1377 assert_equal TightPerson, TightDescendant.base_class 1378 1379 assert_equal Post, Post.base_class 1380 assert_equal Post, SpecialPost.base_class 1381 assert_equal Post, StiPost.base_class 1382 assert_equal SubStiPost, SubStiPost.base_class 1383 end 1384 1385 def test_descends_from_active_record 1386 # Tries to call Object.abstract_class? 1387 assert_raise(NoMethodError) do 1388 ActiveRecord::Base.descends_from_active_record? 1389 end 1390 1391 # Abstract subclass of AR::Base. 1392 assert LoosePerson.descends_from_active_record? 1393 1394 # Concrete subclass of an abstract class. 1395 assert LooseDescendant.descends_from_active_record? 1396 1397 # Concrete subclass of AR::Base. 1398 assert TightPerson.descends_from_active_record? 1399 1400 # Concrete subclass of a concrete class but has no type column. 1401 assert TightDescendant.descends_from_active_record? 1402 1403 # Concrete subclass of AR::Base. 1404 assert Post.descends_from_active_record? 1405 1406 # Abstract subclass of a concrete class which has a type column. 1407 # This is pathological, as you'll never have Sub < Abstract < Concrete. 1408 assert !StiPost.descends_from_active_record? 1409 1410 # Concrete subclasses an abstract class which has a type column. 1411 assert SubStiPost.descends_from_active_record? 1412 end 1413 1414 def test_find_on_abstract_base_class_doesnt_use_type_condition 1415 old_class = LooseDescendant 1416 Object.send :remove_const, :LooseDescendant 1417 1418 descendant = old_class.create! 1419 assert_not_nil LoosePerson.find(descendant.id), "Should have found instance of LooseDescendant when finding abstract LoosePerson: #{descendant.inspect}" 1420 ensure 1421 unless Object.const_defined?(:LooseDescendant) 1422 Object.const_set :LooseDescendant, old_class 1423 end 1371 1424 end 1372 1425 trunk/activerecord/test/fixtures/db_definitions/mysql.sql
r4808 r5660 160 160 `title` VARCHAR(255) NOT NULL, 161 161 `body` TEXT NOT NULL, 162 `type` VARCHAR(255) NOTNULL162 `type` VARCHAR(255) default NULL 163 163 ) TYPE=InnoDB; 164 164 … … 167 167 `post_id` INTEGER NOT NULL, 168 168 `body` TEXT NOT NULL, 169 `type` VARCHAR(255) NOTNULL169 `type` VARCHAR(255) default NULL 170 170 ) TYPE=InnoDB; 171 171 … … 185 185 `id` int(11) NOT NULL auto_increment, 186 186 `name` VARCHAR(255) NOT NULL, 187 `type` VARCHAR(255) NOTNULL,187 `type` VARCHAR(255) default NULL, 188 188 PRIMARY KEY (`id`) 189 189 ) TYPE=InnoDB; trunk/activerecord/test/fixtures/db_definitions/sqlite.sql
r4596 r5660 145 145 'author_id' INTEGER, 146 146 'title' VARCHAR(255) NOT NULL, 147 'type' VARCHAR(255) NOT NULL,147 'type' VARCHAR(255) DEFAULT NULL, 148 148 'body' TEXT NOT NULL 149 149 ); … … 152 152 'id' INTEGER NOT NULL PRIMARY KEY, 153 153 'post_id' INTEGER NOT NULL, 154 'type' VARCHAR(255) NOT NULL,154 'type' VARCHAR(255) DEFAULT NULL, 155 155 'body' TEXT NOT NULL 156 156 ); trunk/activerecord/test/fixtures/post.rb
r5116 r5660 47 47 end 48 48 49 class SpecialPost < Post; end ;49 class SpecialPost < Post; end 50 50 51 51 class StiPost < Post … … 55 55 56 56 class SubStiPost < StiPost 57 self.table_name = Post.table_name 57 58 end