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.
- data/CHANGELOG +452 -10
- data/RUNNING_UNIT_TESTS +1 -1
- data/lib/active_record.rb +5 -2
- data/lib/active_record/acts/list.rb +1 -1
- data/lib/active_record/acts/tree.rb +29 -25
- data/lib/active_record/aggregations.rb +3 -2
- data/lib/active_record/associations.rb +783 -337
- data/lib/active_record/associations/association_collection.rb +7 -12
- data/lib/active_record/associations/association_proxy.rb +62 -24
- data/lib/active_record/associations/belongs_to_association.rb +27 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +38 -38
- data/lib/active_record/associations/has_many_association.rb +61 -56
- data/lib/active_record/associations/has_many_through_association.rb +144 -0
- data/lib/active_record/associations/has_one_association.rb +22 -16
- data/lib/active_record/base.rb +482 -182
- data/lib/active_record/calculations.rb +225 -0
- data/lib/active_record/callbacks.rb +7 -7
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +162 -47
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +21 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +34 -2
- data/lib/active_record/connection_adapters/db2_adapter.rb +107 -61
- data/lib/active_record/connection_adapters/mysql_adapter.rb +29 -6
- data/lib/active_record/connection_adapters/openbase_adapter.rb +349 -0
- data/lib/active_record/connection_adapters/{oci_adapter.rb → oracle_adapter.rb} +125 -59
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +24 -21
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +47 -8
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +36 -16
- data/lib/active_record/connection_adapters/sybase_adapter.rb +684 -0
- data/lib/active_record/fixtures.rb +42 -17
- data/lib/active_record/locking.rb +36 -15
- data/lib/active_record/migration.rb +111 -8
- data/lib/active_record/observer.rb +25 -1
- data/lib/active_record/reflection.rb +103 -41
- data/lib/active_record/schema.rb +2 -2
- data/lib/active_record/schema_dumper.rb +55 -18
- data/lib/active_record/timestamp.rb +6 -6
- data/lib/active_record/validations.rb +65 -40
- data/lib/active_record/vendor/db2.rb +10 -5
- data/lib/active_record/vendor/simple.rb +693 -702
- data/lib/active_record/version.rb +2 -2
- data/rakefile +4 -4
- data/test/aaa_create_tables_test.rb +25 -6
- data/test/abstract_unit.rb +39 -1
- data/test/adapter_test.rb +31 -4
- data/test/associations_cascaded_eager_loading_test.rb +106 -0
- data/test/associations_go_eager_test.rb +85 -16
- data/test/associations_join_model_test.rb +338 -0
- data/test/associations_test.rb +129 -50
- data/test/base_test.rb +204 -49
- data/test/binary_test.rb +1 -1
- data/test/calculations_test.rb +169 -0
- data/test/callbacks_test.rb +5 -23
- data/test/class_inheritable_attributes_test.rb +1 -1
- data/test/column_alias_test.rb +1 -1
- data/test/connections/native_mysql/connection.rb +1 -0
- data/test/connections/native_openbase/connection.rb +22 -0
- data/test/connections/{native_oci → native_oracle}/connection.rb +7 -9
- data/test/connections/native_sqlite/connection.rb +1 -1
- data/test/connections/native_sqlite3/connection.rb +1 -0
- data/test/connections/native_sqlite3/in_memory_connection.rb +1 -0
- data/test/connections/native_sybase/connection.rb +24 -0
- data/test/defaults_test.rb +18 -0
- data/test/deprecated_associations_test.rb +2 -2
- data/test/deprecated_finder_test.rb +0 -6
- data/test/finder_test.rb +26 -23
- data/test/fixtures/accounts.yml +10 -0
- data/test/fixtures/author.rb +31 -6
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories_posts.yml +4 -0
- data/test/fixtures/categorization.rb +5 -0
- data/test/fixtures/categorizations.yml +11 -0
- data/test/fixtures/category.rb +6 -0
- data/test/fixtures/company.rb +17 -5
- data/test/fixtures/company_in_module.rb +19 -5
- data/test/fixtures/db_definitions/db2.drop.sql +3 -0
- data/test/fixtures/db_definitions/db2.sql +121 -100
- data/test/fixtures/db_definitions/db22.sql +2 -2
- data/test/fixtures/db_definitions/firebird.drop.sql +4 -0
- data/test/fixtures/db_definitions/firebird.sql +26 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +3 -0
- data/test/fixtures/db_definitions/mysql.sql +21 -1
- data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase.sql +282 -0
- data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase2.sql +7 -0
- data/test/fixtures/db_definitions/{oci.drop.sql → oracle.drop.sql} +6 -0
- data/test/fixtures/db_definitions/{oci.sql → oracle.sql} +25 -4
- data/test/fixtures/db_definitions/{oci2.drop.sql → oracle2.drop.sql} +0 -0
- data/test/fixtures/db_definitions/{oci2.sql → oracle2.sql} +0 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +4 -0
- data/test/fixtures/db_definitions/postgresql.sql +22 -1
- data/test/fixtures/db_definitions/schema.rb +32 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +3 -0
- data/test/fixtures/db_definitions/sqlite.sql +18 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +3 -0
- data/test/fixtures/db_definitions/sqlserver.sql +23 -3
- data/test/fixtures/db_definitions/sybase.drop.sql +31 -0
- data/test/fixtures/db_definitions/sybase.sql +204 -0
- data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
- data/test/fixtures/db_definitions/sybase2.sql +5 -0
- data/test/fixtures/developers.yml +6 -1
- data/test/fixtures/developers_projects.yml +4 -0
- data/test/fixtures/funny_jokes.yml +14 -0
- data/test/fixtures/joke.rb +6 -0
- data/test/fixtures/legacy_thing.rb +3 -0
- data/test/fixtures/legacy_things.yml +3 -0
- data/test/fixtures/mixin.rb +1 -1
- data/test/fixtures/person.rb +4 -1
- data/test/fixtures/post.rb +26 -1
- data/test/fixtures/project.rb +1 -0
- data/test/fixtures/reader.rb +4 -0
- data/test/fixtures/readers.yml +4 -0
- data/test/fixtures/reply.rb +2 -1
- data/test/fixtures/tag.rb +5 -0
- data/test/fixtures/tagging.rb +6 -0
- data/test/fixtures/taggings.yml +18 -0
- data/test/fixtures/tags.yml +7 -0
- data/test/fixtures/tasks.yml +2 -2
- data/test/fixtures/topic.rb +2 -2
- data/test/fixtures/topics.yml +1 -0
- data/test/fixtures_test.rb +47 -13
- data/test/inheritance_test.rb +2 -2
- data/test/locking_test.rb +15 -1
- data/test/method_scoping_test.rb +248 -13
- data/test/migration_test.rb +68 -11
- data/test/mixin_nested_set_test.rb +1 -1
- data/test/modules_test.rb +6 -1
- data/test/readonly_test.rb +1 -1
- data/test/reflection_test.rb +63 -9
- data/test/schema_dumper_test.rb +41 -0
- data/test/{synonym_test_oci.rb → synonym_test_oracle.rb} +1 -1
- data/test/threaded_connections_test.rb +10 -0
- data/test/unconnected_test.rb +12 -5
- data/test/validations_test.rb +197 -10
- metadata +295 -260
- data/test/fixtures/db_definitions/create_oracle_db.bat +0 -0
- data/test/fixtures/db_definitions/create_oracle_db.sh +0 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
data/test/callbacks_test.rb
CHANGED
@@ -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
|
-
|
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 =
|
330
|
+
david = ImmutableDeveloper.find(1)
|
342
331
|
david.salary = 10_000_000
|
343
332
|
assert !david.valid?
|
344
333
|
assert !david.save
|
345
|
-
|
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)
|
data/test/column_alias_test.rb
CHANGED
@@ -4,7 +4,7 @@ require 'fixtures/topic'
|
|
4
4
|
class TestColumnAlias < Test::Unit::TestCase
|
5
5
|
fixtures :topics
|
6
6
|
|
7
|
-
QUERY = if '
|
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'
|
@@ -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
|
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
|
-
|
9
|
-
|
8
|
+
# Set these to your database connection strings
|
9
|
+
db = 'activerecord_unit_tests'
|
10
10
|
|
11
11
|
ActiveRecord::Base.establish_connection(
|
12
|
-
:adapter => '
|
13
|
-
:host => '', # can use an oracle SID
|
12
|
+
:adapter => 'oracle',
|
14
13
|
:username => 'arunit',
|
15
14
|
:password => 'arunit',
|
16
|
-
:database =>
|
15
|
+
:database => db
|
17
16
|
)
|
18
17
|
|
19
18
|
Course.establish_connection(
|
20
|
-
:adapter => '
|
21
|
-
:host => '', # can use an oracle SID
|
19
|
+
:adapter => 'oracle',
|
22
20
|
:username => 'arunit2',
|
23
21
|
:password => 'arunit2',
|
24
|
-
:database =>
|
22
|
+
:database => db
|
25
23
|
)
|
@@ -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
|
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
|
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
|
data/test/finder_test.rb
CHANGED
@@ -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).
|
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
|
-
|
290
|
-
|
291
|
-
assert_equal
|
292
|
-
assert_equal
|
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
|
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')
|
data/test/fixtures/accounts.yml
CHANGED
data/test/fixtures/author.rb
CHANGED
@@ -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
|
9
|
-
:
|
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
|
12
|
-
:after_add
|
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
|
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
|
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
|