activerecord 1.13.2 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (144) hide show
  1. data/CHANGELOG +452 -10
  2. data/RUNNING_UNIT_TESTS +1 -1
  3. data/lib/active_record.rb +5 -2
  4. data/lib/active_record/acts/list.rb +1 -1
  5. data/lib/active_record/acts/tree.rb +29 -25
  6. data/lib/active_record/aggregations.rb +3 -2
  7. data/lib/active_record/associations.rb +783 -337
  8. data/lib/active_record/associations/association_collection.rb +7 -12
  9. data/lib/active_record/associations/association_proxy.rb +62 -24
  10. data/lib/active_record/associations/belongs_to_association.rb +27 -46
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
  12. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +38 -38
  13. data/lib/active_record/associations/has_many_association.rb +61 -56
  14. data/lib/active_record/associations/has_many_through_association.rb +144 -0
  15. data/lib/active_record/associations/has_one_association.rb +22 -16
  16. data/lib/active_record/base.rb +482 -182
  17. data/lib/active_record/calculations.rb +225 -0
  18. data/lib/active_record/callbacks.rb +7 -7
  19. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +162 -47
  20. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  21. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +2 -1
  22. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +21 -1
  23. data/lib/active_record/connection_adapters/abstract_adapter.rb +34 -2
  24. data/lib/active_record/connection_adapters/db2_adapter.rb +107 -61
  25. data/lib/active_record/connection_adapters/mysql_adapter.rb +29 -6
  26. data/lib/active_record/connection_adapters/openbase_adapter.rb +349 -0
  27. data/lib/active_record/connection_adapters/{oci_adapter.rb → oracle_adapter.rb} +125 -59
  28. data/lib/active_record/connection_adapters/postgresql_adapter.rb +24 -21
  29. data/lib/active_record/connection_adapters/sqlite_adapter.rb +47 -8
  30. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +36 -16
  31. data/lib/active_record/connection_adapters/sybase_adapter.rb +684 -0
  32. data/lib/active_record/fixtures.rb +42 -17
  33. data/lib/active_record/locking.rb +36 -15
  34. data/lib/active_record/migration.rb +111 -8
  35. data/lib/active_record/observer.rb +25 -1
  36. data/lib/active_record/reflection.rb +103 -41
  37. data/lib/active_record/schema.rb +2 -2
  38. data/lib/active_record/schema_dumper.rb +55 -18
  39. data/lib/active_record/timestamp.rb +6 -6
  40. data/lib/active_record/validations.rb +65 -40
  41. data/lib/active_record/vendor/db2.rb +10 -5
  42. data/lib/active_record/vendor/simple.rb +693 -702
  43. data/lib/active_record/version.rb +2 -2
  44. data/rakefile +4 -4
  45. data/test/aaa_create_tables_test.rb +25 -6
  46. data/test/abstract_unit.rb +39 -1
  47. data/test/adapter_test.rb +31 -4
  48. data/test/associations_cascaded_eager_loading_test.rb +106 -0
  49. data/test/associations_go_eager_test.rb +85 -16
  50. data/test/associations_join_model_test.rb +338 -0
  51. data/test/associations_test.rb +129 -50
  52. data/test/base_test.rb +204 -49
  53. data/test/binary_test.rb +1 -1
  54. data/test/calculations_test.rb +169 -0
  55. data/test/callbacks_test.rb +5 -23
  56. data/test/class_inheritable_attributes_test.rb +1 -1
  57. data/test/column_alias_test.rb +1 -1
  58. data/test/connections/native_mysql/connection.rb +1 -0
  59. data/test/connections/native_openbase/connection.rb +22 -0
  60. data/test/connections/{native_oci → native_oracle}/connection.rb +7 -9
  61. data/test/connections/native_sqlite/connection.rb +1 -1
  62. data/test/connections/native_sqlite3/connection.rb +1 -0
  63. data/test/connections/native_sqlite3/in_memory_connection.rb +1 -0
  64. data/test/connections/native_sybase/connection.rb +24 -0
  65. data/test/defaults_test.rb +18 -0
  66. data/test/deprecated_associations_test.rb +2 -2
  67. data/test/deprecated_finder_test.rb +0 -6
  68. data/test/finder_test.rb +26 -23
  69. data/test/fixtures/accounts.yml +10 -0
  70. data/test/fixtures/author.rb +31 -6
  71. data/test/fixtures/author_favorites.yml +4 -0
  72. data/test/fixtures/categories/special_categories.yml +9 -0
  73. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  74. data/test/fixtures/categories_posts.yml +4 -0
  75. data/test/fixtures/categorization.rb +5 -0
  76. data/test/fixtures/categorizations.yml +11 -0
  77. data/test/fixtures/category.rb +6 -0
  78. data/test/fixtures/company.rb +17 -5
  79. data/test/fixtures/company_in_module.rb +19 -5
  80. data/test/fixtures/db_definitions/db2.drop.sql +3 -0
  81. data/test/fixtures/db_definitions/db2.sql +121 -100
  82. data/test/fixtures/db_definitions/db22.sql +2 -2
  83. data/test/fixtures/db_definitions/firebird.drop.sql +4 -0
  84. data/test/fixtures/db_definitions/firebird.sql +26 -0
  85. data/test/fixtures/db_definitions/mysql.drop.sql +3 -0
  86. data/test/fixtures/db_definitions/mysql.sql +21 -1
  87. data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
  88. data/test/fixtures/db_definitions/openbase.sql +282 -0
  89. data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
  90. data/test/fixtures/db_definitions/openbase2.sql +7 -0
  91. data/test/fixtures/db_definitions/{oci.drop.sql → oracle.drop.sql} +6 -0
  92. data/test/fixtures/db_definitions/{oci.sql → oracle.sql} +25 -4
  93. data/test/fixtures/db_definitions/{oci2.drop.sql → oracle2.drop.sql} +0 -0
  94. data/test/fixtures/db_definitions/{oci2.sql → oracle2.sql} +0 -0
  95. data/test/fixtures/db_definitions/postgresql.drop.sql +4 -0
  96. data/test/fixtures/db_definitions/postgresql.sql +22 -1
  97. data/test/fixtures/db_definitions/schema.rb +32 -0
  98. data/test/fixtures/db_definitions/sqlite.drop.sql +3 -0
  99. data/test/fixtures/db_definitions/sqlite.sql +18 -0
  100. data/test/fixtures/db_definitions/sqlserver.drop.sql +3 -0
  101. data/test/fixtures/db_definitions/sqlserver.sql +23 -3
  102. data/test/fixtures/db_definitions/sybase.drop.sql +31 -0
  103. data/test/fixtures/db_definitions/sybase.sql +204 -0
  104. data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
  105. data/test/fixtures/db_definitions/sybase2.sql +5 -0
  106. data/test/fixtures/developers.yml +6 -1
  107. data/test/fixtures/developers_projects.yml +4 -0
  108. data/test/fixtures/funny_jokes.yml +14 -0
  109. data/test/fixtures/joke.rb +6 -0
  110. data/test/fixtures/legacy_thing.rb +3 -0
  111. data/test/fixtures/legacy_things.yml +3 -0
  112. data/test/fixtures/mixin.rb +1 -1
  113. data/test/fixtures/person.rb +4 -1
  114. data/test/fixtures/post.rb +26 -1
  115. data/test/fixtures/project.rb +1 -0
  116. data/test/fixtures/reader.rb +4 -0
  117. data/test/fixtures/readers.yml +4 -0
  118. data/test/fixtures/reply.rb +2 -1
  119. data/test/fixtures/tag.rb +5 -0
  120. data/test/fixtures/tagging.rb +6 -0
  121. data/test/fixtures/taggings.yml +18 -0
  122. data/test/fixtures/tags.yml +7 -0
  123. data/test/fixtures/tasks.yml +2 -2
  124. data/test/fixtures/topic.rb +2 -2
  125. data/test/fixtures/topics.yml +1 -0
  126. data/test/fixtures_test.rb +47 -13
  127. data/test/inheritance_test.rb +2 -2
  128. data/test/locking_test.rb +15 -1
  129. data/test/method_scoping_test.rb +248 -13
  130. data/test/migration_test.rb +68 -11
  131. data/test/mixin_nested_set_test.rb +1 -1
  132. data/test/modules_test.rb +6 -1
  133. data/test/readonly_test.rb +1 -1
  134. data/test/reflection_test.rb +63 -9
  135. data/test/schema_dumper_test.rb +41 -0
  136. data/test/{synonym_test_oci.rb → synonym_test_oracle.rb} +1 -1
  137. data/test/threaded_connections_test.rb +10 -0
  138. data/test/unconnected_test.rb +12 -5
  139. data/test/validations_test.rb +197 -10
  140. metadata +295 -260
  141. data/test/fixtures/db_definitions/create_oracle_db.bat +0 -0
  142. data/test/fixtures/db_definitions/create_oracle_db.sh +0 -0
  143. data/test/fixtures/fixture_database.sqlite +0 -0
  144. data/test/fixtures/fixture_database_2.sqlite +0 -0
@@ -324,39 +324,21 @@ class CallbacksTest < Test::Unit::TestCase
324
324
  def test_before_save_returning_false
325
325
  david = ImmutableDeveloper.find(1)
326
326
  assert david.valid?
327
- assert david.save
328
- assert david.cancelled?
329
-
330
- david = ImmutableDeveloper.find(1)
331
- david.salary = 10_000_000
332
- assert !david.valid?
333
327
  assert !david.save
334
- assert !david.cancelled?
335
-
336
- david = ImmutableMethodDeveloper.find(1)
337
- assert david.valid?
338
- assert david.save
339
- assert david.cancelled?
328
+ assert_raises(ActiveRecord::RecordNotSaved) { david.save! }
340
329
 
341
- david = ImmutableMethodDeveloper.find(1)
330
+ david = ImmutableDeveloper.find(1)
342
331
  david.salary = 10_000_000
343
332
  assert !david.valid?
344
333
  assert !david.save
345
- assert !david.cancelled?
334
+ assert_raises(ActiveRecord::RecordInvalid) { david.save! }
346
335
  end
347
336
 
348
337
  def test_before_destroy_returning_false
349
338
  david = ImmutableDeveloper.find(1)
350
- david.destroy
351
- assert david.cancelled?
339
+ assert !david.destroy
352
340
  assert_not_nil ImmutableDeveloper.find_by_id(1)
353
-
354
- david = ImmutableMethodDeveloper.find(1)
355
- david.destroy
356
- assert david.cancelled?
357
- assert_not_nil ImmutableMethodDeveloper.find_by_id(1)
358
- end
359
-
341
+ end
360
342
 
361
343
  def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
362
344
  david = CallbackDeveloper.find(1)
@@ -1,6 +1,6 @@
1
1
  require 'test/unit'
2
2
  require 'abstract_unit'
3
- require 'active_support/class_inheritable_attributes'
3
+ require 'active_support/core_ext/class/inheritable_attributes'
4
4
 
5
5
  class A
6
6
  include ClassInheritableAttributes
@@ -4,7 +4,7 @@ require 'fixtures/topic'
4
4
  class TestColumnAlias < Test::Unit::TestCase
5
5
  fixtures :topics
6
6
 
7
- QUERY = if 'OCI' == ActiveRecord::Base.connection.adapter_name
7
+ QUERY = if 'Oracle' == ActiveRecord::Base.connection.adapter_name
8
8
  'SELECT id AS pk FROM topics WHERE ROWNUM < 2'
9
9
  else
10
10
  'SELECT id AS pk FROM topics'
@@ -10,6 +10,7 @@ db2 = 'activerecord_unittest2'
10
10
  ActiveRecord::Base.establish_connection(
11
11
  :adapter => "mysql",
12
12
  :username => "rails",
13
+ :encoding => "utf8",
13
14
  :database => db1
14
15
  )
15
16
 
@@ -0,0 +1,22 @@
1
+ print "Using native OpenBase\n"
2
+ require_dependency 'fixtures/course'
3
+ require 'logger'
4
+
5
+ ActiveRecord::Base.logger = Logger.new("debug.log")
6
+
7
+ db1 = 'activerecord_unittest'
8
+ db2 = 'activerecord_unittest2'
9
+
10
+ ActiveRecord::Base.establish_connection(
11
+ :adapter => "openbase",
12
+ :username => "admin",
13
+ :password => "",
14
+ :database => db1
15
+ )
16
+
17
+ Course.establish_connection(
18
+ :adapter => "openbase",
19
+ :username => "admin",
20
+ :password => "",
21
+ :database => db2
22
+ )
@@ -1,25 +1,23 @@
1
- print "Using OCI Oracle\n"
1
+ print "Using Oracle\n"
2
2
  require_dependency 'fixtures/course'
3
3
  require 'logger'
4
4
 
5
5
  ActiveRecord::Base.logger = Logger.new STDOUT
6
6
  ActiveRecord::Base.logger.level = Logger::WARN
7
7
 
8
- db1 = 'activerecord_unittest'
9
- db2 = 'activerecord_unittest2'
8
+ # Set these to your database connection strings
9
+ db = 'activerecord_unit_tests'
10
10
 
11
11
  ActiveRecord::Base.establish_connection(
12
- :adapter => 'oci',
13
- :host => '', # can use an oracle SID
12
+ :adapter => 'oracle',
14
13
  :username => 'arunit',
15
14
  :password => 'arunit',
16
- :database => db1
15
+ :database => db
17
16
  )
18
17
 
19
18
  Course.establish_connection(
20
- :adapter => 'oci',
21
- :host => '', # can use an oracle SID
19
+ :adapter => 'oracle',
22
20
  :username => 'arunit2',
23
21
  :password => 'arunit2',
24
- :database => db2
22
+ :database => db
25
23
  )
@@ -34,4 +34,4 @@ end
34
34
 
35
35
  make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql')
36
36
  make_connection(Course, sqlite_test_db2, 'sqlite2.sql')
37
-
37
+ load(File.join(BASE_DIR, 'db_definitions', 'schema.rb'))
@@ -34,3 +34,4 @@ end
34
34
 
35
35
  make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql')
36
36
  make_connection(Course, sqlite_test_db2, 'sqlite2.sql')
37
+ load(File.join(BASE_DIR, 'db_definitions', 'schema.rb'))
@@ -15,3 +15,4 @@ end
15
15
 
16
16
  make_connection(ActiveRecord::Base, 'sqlite.sql')
17
17
  make_connection(Course, 'sqlite2.sql')
18
+ load("#{File.dirname(__FILE__)}/../../fixtures/db_definitions/schema.rb"))
@@ -0,0 +1,24 @@
1
+ print "Using native Sybase Open Client\n"
2
+ require_dependency 'fixtures/course'
3
+ require 'logger'
4
+
5
+ ActiveRecord::Base.logger = Logger.new("debug.log")
6
+
7
+ db1 = 'activerecord_unittest'
8
+ db2 = 'activerecord_unittest2'
9
+
10
+ ActiveRecord::Base.establish_connection(
11
+ :adapter => "sybase",
12
+ :host => "database_ASE",
13
+ :username => "sa",
14
+ :password => "",
15
+ :database => db1
16
+ )
17
+
18
+ Course.establish_connection(
19
+ :adapter => "sybase",
20
+ :host => "database_ASE",
21
+ :username => "sa",
22
+ :password => "",
23
+ :database => db2
24
+ )
@@ -0,0 +1,18 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/default'
3
+
4
+ class DefaultsTest < Test::Unit::TestCase
5
+ if %w(PostgreSQL).include? ActiveRecord::Base.connection.adapter_name
6
+ def test_default_integers
7
+ default = Default.new
8
+ assert_instance_of(Fixnum, default.positive_integer)
9
+ assert_equal(default.positive_integer, 1)
10
+ assert_instance_of(Fixnum, default.negative_integer)
11
+ assert_equal(default.negative_integer, -1)
12
+ end
13
+ else
14
+ def test_dummy
15
+ assert true
16
+ end
17
+ end
18
+ end
@@ -181,7 +181,7 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
181
181
 
182
182
  active_record = Project.find(1)
183
183
  assert active_record.has_developers?
184
- assert_equal 2, active_record.developers_count
184
+ assert_equal 3, active_record.developers_count
185
185
  assert active_record.developers.include?(david)
186
186
  end
187
187
 
@@ -192,7 +192,7 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
192
192
  david.remove_projects(active_record)
193
193
 
194
194
  assert_equal 1, david.projects_count
195
- assert_equal 1, active_record.developers_count
195
+ assert_equal 2, active_record.developers_count
196
196
  end
197
197
 
198
198
  def test_has_and_belongs_to_many_zero
@@ -74,12 +74,6 @@ class DeprecatedFinderTest < Test::Unit::TestCase
74
74
  assert_nil Company.find_first(["name = :name", { :name => "37signals!" }])
75
75
  assert_nil Company.find_first(["name = :name", { :name => "37signals!' OR 1=1" }])
76
76
  assert_kind_of Time, Topic.find_first(["id = :id", { :id => 1 }]).written_on
77
- assert_raises(ActiveRecord::PreparedStatementInvalid) {
78
- Company.find_first(["id=:id and name=:name", { :id=>3 }])
79
- }
80
- assert_raises(ActiveRecord::PreparedStatementInvalid) {
81
- Company.find_first(["id=:id", { :id=>3, :name=>"37signals!" }])
82
- }
83
77
  end
84
78
 
85
79
  def test_count
@@ -1,12 +1,13 @@
1
1
  require 'abstract_unit'
2
2
  require 'fixtures/company'
3
3
  require 'fixtures/topic'
4
+ require 'fixtures/reply'
4
5
  require 'fixtures/entrant'
5
6
  require 'fixtures/developer'
6
7
  require 'fixtures/post'
7
8
 
8
9
  class FinderTest < Test::Unit::TestCase
9
- fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts
10
+ fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :accounts
10
11
 
11
12
  def test_find
12
13
  assert_equal(topics(:first).title, Topic.find(1).title)
@@ -57,6 +58,11 @@ class FinderTest < Test::Unit::TestCase
57
58
  assert_equal(entrants(:third).name, entrants.first.name)
58
59
  end
59
60
 
61
+ def test_find_all_with_limit_and_offset_and_multiple_orderings
62
+ developers = Developer.find(:all, :order => "salary ASC, id DESC", :limit => 3, :offset => 1)
63
+ assert_equal ["David", "fixture_10", "fixture_9"], developers.collect {|d| d.name}
64
+ end
65
+
60
66
  def test_find_with_limit_and_condition
61
67
  developers = Developer.find(:all, :order => "id DESC", :conditions => "salary = 100000", :limit => 3, :offset =>7)
62
68
  assert_equal(1, developers.size)
@@ -92,7 +98,7 @@ class FinderTest < Test::Unit::TestCase
92
98
  Topic.find(1).parent
93
99
  }
94
100
 
95
- Topic.find(2).parent
101
+ Topic.find(2).topic
96
102
  end
97
103
 
98
104
  def test_find_only_some_columns
@@ -157,22 +163,6 @@ class FinderTest < Test::Unit::TestCase
157
163
  assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!" }])
158
164
  assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!' OR 1=1" }])
159
165
  assert_kind_of Time, Topic.find(:first, :conditions => ["id = :id", { :id => 1 }]).written_on
160
- assert_raises(ActiveRecord::PreparedStatementInvalid) {
161
- Company.find(:first, :conditions => ["id=:id and name=:name", { :id=>3 }])
162
- }
163
- assert_raises(ActiveRecord::PreparedStatementInvalid) {
164
- Company.find(:first, :conditions => ["id=:id", { :id=>3, :name=>"37signals!" }])
165
- }
166
- end
167
-
168
- def test_named_bind_arity
169
- assert_nothing_raised { bind '', {} }
170
- assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '', :a => 1 }
171
- assert_raises(ActiveRecord::PreparedStatementInvalid) { bind ':a', {} } # ' ruby-mode
172
- assert_nothing_raised { bind ':a', :a => 1 } # ' ruby-mode
173
- assert_raises(ActiveRecord::PreparedStatementInvalid) { bind ':a', :a => 1, :b => 2 } # ' ruby-mode
174
- assert_nothing_raised { bind ':a :a', :a => 1 } # ' ruby-mode
175
- assert_raises(ActiveRecord::PreparedStatementInvalid) { bind ':a :a', :a => 1, :b => 2 } # ' ruby-mode
176
166
  end
177
167
 
178
168
  def test_bind_enumerable
@@ -216,6 +206,19 @@ class FinderTest < Test::Unit::TestCase
216
206
  assert_nil Topic.find_by_title("The First Topic!")
217
207
  end
218
208
 
209
+ def test_find_by_one_attribute_with_order_option
210
+ assert_equal accounts(:signals37), Account.find_by_credit_limit(50, :order => 'id')
211
+ assert_equal accounts(:rails_core_account), Account.find_by_credit_limit(50, :order => 'id DESC')
212
+ end
213
+
214
+ def test_find_by_one_attribute_with_conditions
215
+ assert_equal accounts(:rails_core_account), Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6])
216
+ end
217
+
218
+ def test_find_by_one_attribute_with_several_options
219
+ assert_equal accounts(:unknown), Account.find_by_credit_limit(50, :order => 'id DESC', :conditions => ['id != ?', 3])
220
+ end
221
+
219
222
  def test_find_by_one_missing_attribute
220
223
  assert_raises(NoMethodError) { Topic.find_by_undertitle("The First Topic!") }
221
224
  end
@@ -286,10 +289,10 @@ class FinderTest < Test::Unit::TestCase
286
289
  end
287
290
 
288
291
  def test_find_or_create_from_two_attributes
289
- number_of_companies = Company.count
290
- sig38 = Company.find_or_create_by_name("38signals")
291
- assert_equal number_of_companies + 1, Company.count
292
- assert_equal sig38, Company.find_or_create_by_name("38signals")
292
+ number_of_topics = Topic.count
293
+ another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
294
+ assert_equal number_of_topics + 1, Topic.count
295
+ assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
293
296
  end
294
297
 
295
298
  def test_find_with_bad_sql
@@ -341,7 +344,7 @@ class FinderTest < Test::Unit::TestCase
341
344
  :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
342
345
  :conditions => 'project_id=1'
343
346
  )
344
- assert_equal 2, developers_on_project_one.length
347
+ assert_equal 3, developers_on_project_one.length
345
348
  developer_names = developers_on_project_one.map { |d| d.name }
346
349
  assert developer_names.include?('David')
347
350
  assert developer_names.include?('Jamis')
@@ -11,3 +11,13 @@ rails_core_account:
11
11
  id: 3
12
12
  firm_id: 6
13
13
  credit_limit: 50
14
+
15
+ last_account:
16
+ id: 4
17
+ firm_id: 2
18
+ credit_limit: 60
19
+
20
+ rails_core_account_2:
21
+ id: 5
22
+ firm_id: 6
23
+ credit_limit: 55
@@ -3,20 +3,36 @@ class Author < ActiveRecord::Base
3
3
  has_many :posts_with_comments, :include => :comments, :class_name => "Post"
4
4
  has_many :posts_with_categories, :include => :categories, :class_name => "Post"
5
5
  has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post"
6
+ has_many :comments, :through => :posts
7
+ has_many :funky_comments, :through => :posts, :source => :comments
6
8
 
9
+ has_many :special_posts, :class_name => "Post"
10
+ has_many :hello_posts, :class_name => "Post", :conditions=>"\#{aliased_table_name}.body = 'hello'"
11
+ has_many :nonexistent_posts, :class_name => "Post", :conditions=>"\#{aliased_table_name}.body = 'nonexistent'"
7
12
  has_many :posts_with_callbacks, :class_name => "Post", :before_add => :log_before_adding,
8
- :after_add => :log_after_adding, :before_remove => :log_before_removing,
9
- :after_remove => :log_after_removing
13
+ :after_add => :log_after_adding,
14
+ :before_remove => :log_before_removing,
15
+ :after_remove => :log_after_removing
10
16
  has_many :posts_with_proc_callbacks, :class_name => "Post",
11
- :before_add => Proc.new {|o, r| o.post_log << "before_adding#{r.id}"},
12
- :after_add => Proc.new {|o, r| o.post_log << "after_adding#{r.id}"},
17
+ :before_add => Proc.new {|o, r| o.post_log << "before_adding#{r.id}"},
18
+ :after_add => Proc.new {|o, r| o.post_log << "after_adding#{r.id}"},
13
19
  :before_remove => Proc.new {|o, r| o.post_log << "before_removing#{r.id}"},
14
- :after_remove => Proc.new {|o, r| o.post_log << "after_removing#{r.id}"}
20
+ :after_remove => Proc.new {|o, r| o.post_log << "after_removing#{r.id}"}
15
21
  has_many :posts_with_multiple_callbacks, :class_name => "Post",
16
22
  :before_add => [:log_before_adding, Proc.new {|o, r| o.post_log << "before_adding_proc#{r.id}"}],
17
- :after_add => [:log_after_adding, Proc.new {|o, r| o.post_log << "after_adding_proc#{r.id}"}]
23
+ :after_add => [:log_after_adding, Proc.new {|o, r| o.post_log << "after_adding_proc#{r.id}"}]
18
24
  has_many :unchangable_posts, :class_name => "Post", :before_add => :raise_exception, :after_add => :log_after_adding
19
25
 
26
+ has_many :categorizations
27
+ has_many :categories, :through => :categorizations
28
+
29
+ has_many :nothings, :through => :kateggorisatons, :class_name => 'Category'
30
+
31
+ has_many :author_favorites
32
+ has_many :favorite_authors, :through => :author_favorites, :order => 'name'
33
+
34
+ belongs_to :author_address
35
+
20
36
  attr_accessor :post_log
21
37
 
22
38
  def after_initialize
@@ -44,3 +60,12 @@ class Author < ActiveRecord::Base
44
60
  raise Exception.new("You can't add a post")
45
61
  end
46
62
  end
63
+
64
+ class AuthorAddress < ActiveRecord::Base
65
+ has_one :author
66
+ end
67
+
68
+ class AuthorFavorite < ActiveRecord::Base
69
+ belongs_to :author
70
+ belongs_to :favorite_author, :class_name => "Author", :foreign_key => 'favorite_author_id'
71
+ end
@@ -0,0 +1,4 @@
1
+ david_mary:
2
+ id: 1
3
+ author_id: 1
4
+ favorite_author_id: 2
@@ -0,0 +1,9 @@
1
+ sub_special_1:
2
+ id: 100
3
+ name: A special category in a subdir file
4
+ type: SpecialCategory
5
+
6
+ sub_special_2:
7
+ id: 101
8
+ name: Another special category
9
+ type: SpecialCategory
@@ -0,0 +1,4 @@
1
+ sub_special_3:
2
+ id: 102
3
+ name: A special category in an arbitrarily named subsubdir file
4
+ type: SpecialCategory
@@ -17,3 +17,7 @@ general_sti_habtm:
17
17
  sti_test_sti_habtm:
18
18
  category_id: 3
19
19
  post_id: 6
20
+
21
+ general_hello:
22
+ category_id: 1
23
+ post_id: 4
@@ -0,0 +1,5 @@
1
+ class Categorization < ActiveRecord::Base
2
+ belongs_to :post
3
+ belongs_to :category
4
+ belongs_to :author
5
+ end
@@ -0,0 +1,11 @@
1
+ david_welcome_general:
2
+ id: 1
3
+ author_id: 1
4
+ post_id: 1
5
+ category_id: 1
6
+
7
+ mary_thinking_sti:
8
+ id: 2
9
+ author_id: 2
10
+ post_id: 2
11
+ category_id: 3