activerecord 1.10.1 → 1.11.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 +187 -19
- data/RUNNING_UNIT_TESTS +11 -0
- data/lib/active_record.rb +3 -1
- data/lib/active_record/acts/list.rb +25 -14
- data/lib/active_record/acts/nested_set.rb +4 -4
- data/lib/active_record/acts/tree.rb +18 -1
- data/lib/active_record/associations.rb +90 -17
- data/lib/active_record/associations/association_collection.rb +44 -5
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +17 -4
- data/lib/active_record/associations/has_many_association.rb +13 -3
- data/lib/active_record/associations/has_one_association.rb +19 -0
- data/lib/active_record/base.rb +292 -268
- data/lib/active_record/callbacks.rb +14 -14
- data/lib/active_record/connection_adapters/abstract_adapter.rb +137 -75
- data/lib/active_record/connection_adapters/db2_adapter.rb +10 -8
- data/lib/active_record/connection_adapters/mysql_adapter.rb +91 -64
- data/lib/active_record/connection_adapters/oci_adapter.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +113 -60
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +15 -12
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +159 -132
- data/lib/active_record/fixtures.rb +59 -12
- data/lib/active_record/locking.rb +10 -9
- data/lib/active_record/migration.rb +112 -5
- data/lib/active_record/query_cache.rb +64 -0
- data/lib/active_record/timestamp.rb +10 -8
- data/lib/active_record/validations.rb +121 -26
- data/rakefile +16 -10
- data/test/aaa_create_tables_test.rb +26 -48
- data/test/abstract_unit.rb +3 -0
- data/test/aggregations_test.rb +19 -19
- data/test/association_callbacks_test.rb +110 -0
- data/test/associations_go_eager_test.rb +48 -14
- data/test/associations_test.rb +344 -142
- data/test/base_test.rb +150 -31
- data/test/binary_test.rb +7 -0
- data/test/callbacks_test.rb +24 -5
- data/test/column_alias_test.rb +2 -2
- data/test/connections/native_sqlserver_odbc/connection.rb +26 -0
- data/test/deprecated_associations_test.rb +27 -28
- data/test/deprecated_finder_test.rb +8 -9
- data/test/finder_test.rb +52 -17
- data/test/fixtures/author.rb +39 -0
- data/test/fixtures/categories.yml +7 -0
- data/test/fixtures/categories_posts.yml +8 -0
- data/test/fixtures/category.rb +2 -0
- data/test/fixtures/comment.rb +3 -1
- data/test/fixtures/comments.yml +43 -1
- data/test/fixtures/companies.yml +14 -0
- data/test/fixtures/company.rb +1 -1
- data/test/fixtures/computers.yml +2 -1
- data/test/fixtures/db_definitions/db2.sql +7 -2
- data/test/fixtures/db_definitions/mysql.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql.sql +11 -6
- data/test/fixtures/db_definitions/oci.sql +7 -2
- data/test/fixtures/db_definitions/postgresql.drop.sql +3 -1
- data/test/fixtures/db_definitions/postgresql.sql +8 -5
- data/test/fixtures/db_definitions/sqlite.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite.sql +9 -4
- data/test/fixtures/db_definitions/sqlserver.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver.sql +12 -7
- data/test/fixtures/developer.rb +8 -1
- data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
- data/test/fixtures/post.rb +8 -2
- data/test/fixtures/posts.yml +21 -0
- data/test/fixtures/project.rb +14 -1
- data/test/fixtures/subscriber.rb +3 -0
- data/test/fixtures_test.rb +14 -0
- data/test/inheritance_test.rb +30 -22
- data/test/lifecycle_test.rb +3 -4
- data/test/locking_test.rb +2 -4
- data/test/migration_test.rb +186 -0
- data/test/mixin_nested_set_test.rb +19 -19
- data/test/mixin_test.rb +88 -88
- data/test/modules_test.rb +5 -10
- data/test/multiple_db_test.rb +2 -0
- data/test/pk_test.rb +8 -12
- data/test/reflection_test.rb +8 -4
- data/test/schema_test_postgresql.rb +63 -0
- data/test/thread_safety_test.rb +4 -1
- data/test/transactions_test.rb +9 -2
- data/test/unconnected_test.rb +1 -0
- data/test/validations_test.rb +151 -8
- metadata +11 -5
- data/test/migration_mysql.rb +0 -104
data/test/modules_test.rb
CHANGED
@@ -2,22 +2,17 @@ require 'abstract_unit'
|
|
2
2
|
require 'fixtures/company_in_module'
|
3
3
|
|
4
4
|
class ModulesTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
create_fixtures "accounts"
|
7
|
-
create_fixtures "companies"
|
8
|
-
create_fixtures "projects"
|
9
|
-
create_fixtures "developers"
|
10
|
-
end
|
5
|
+
fixtures :accounts, :companies, :projects, :developers
|
11
6
|
|
12
7
|
def test_module_spanning_associations
|
13
|
-
assert MyApplication::Business::Firm.
|
14
|
-
firm = MyApplication::Business::Firm.
|
8
|
+
assert MyApplication::Business::Firm.find(:first).has_clients?, "Firm should have clients"
|
9
|
+
firm = MyApplication::Business::Firm.find(:first)
|
15
10
|
assert_nil firm.class.table_name.match('::'), "Firm shouldn't have the module appear in its table name"
|
16
11
|
assert_equal 2, firm.clients_count, "Firm should have two clients"
|
17
12
|
end
|
18
13
|
|
19
14
|
def test_module_spanning_has_and_belongs_to_many_associations
|
20
|
-
project = MyApplication::Business::Project.
|
15
|
+
project = MyApplication::Business::Project.find(:first)
|
21
16
|
project.developers << MyApplication::Business::Developer.create("name" => "John")
|
22
17
|
assert "John", project.developers.last.name
|
23
18
|
end
|
@@ -25,4 +20,4 @@ class ModulesTest < Test::Unit::TestCase
|
|
25
20
|
def test_associations_spanning_cross_modules
|
26
21
|
assert MyApplication::Billing::Account.find(1).has_firm?, "37signals account should be able to backtrack"
|
27
22
|
end
|
28
|
-
end
|
23
|
+
end
|
data/test/multiple_db_test.rb
CHANGED
@@ -3,6 +3,8 @@ require 'fixtures/course'
|
|
3
3
|
require 'fixtures/entrant'
|
4
4
|
|
5
5
|
class MultipleDbTest < Test::Unit::TestCase
|
6
|
+
self.use_transactional_fixtures = false
|
7
|
+
|
6
8
|
def setup
|
7
9
|
@courses = create_fixtures("courses") { Course.retrieve_connection }
|
8
10
|
@entrants = create_fixtures("entrants")
|
data/test/pk_test.rb
CHANGED
@@ -4,17 +4,13 @@ require 'fixtures/subscriber'
|
|
4
4
|
require 'fixtures/movie'
|
5
5
|
|
6
6
|
class PrimaryKeysTest < Test::Unit::TestCase
|
7
|
-
|
8
|
-
@topics = create_fixtures "topics"
|
9
|
-
@subscribers = create_fixtures "subscribers"
|
10
|
-
@movies = create_fixtures "movies"
|
11
|
-
end
|
7
|
+
fixtures :topics, :subscribers, :movies
|
12
8
|
|
13
9
|
def test_integer_key
|
14
10
|
topic = Topic.find(1)
|
15
|
-
assert_equal(
|
11
|
+
assert_equal(topics(:first).author_name, topic.author_name)
|
16
12
|
topic = Topic.find(2)
|
17
|
-
assert_equal(
|
13
|
+
assert_equal(topics(:second).author_name, topic.author_name)
|
18
14
|
|
19
15
|
topic = Topic.new
|
20
16
|
topic.title = "New Topic"
|
@@ -27,10 +23,10 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
27
23
|
end
|
28
24
|
|
29
25
|
def test_string_key
|
30
|
-
subscriber = Subscriber.find(
|
31
|
-
assert_equal(
|
32
|
-
subscriber = Subscriber.find(
|
33
|
-
assert_equal(
|
26
|
+
subscriber = Subscriber.find(subscribers(:first).nick)
|
27
|
+
assert_equal(subscribers(:first).name, subscriber.name)
|
28
|
+
subscriber = Subscriber.find(subscribers(:second).nick)
|
29
|
+
assert_equal(subscribers(:second).name, subscriber.name)
|
34
30
|
|
35
31
|
subscriber = Subscriber.new
|
36
32
|
subscriber.id = "jdoe"
|
@@ -43,7 +39,7 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
43
39
|
end
|
44
40
|
|
45
41
|
def test_find_with_more_than_one_string_key
|
46
|
-
assert_equal 2, Subscriber.find(
|
42
|
+
assert_equal 2, Subscriber.find(subscribers(:first).nick, subscribers(:second).nick).length
|
47
43
|
end
|
48
44
|
|
49
45
|
def test_primary_key_prefix
|
data/test/reflection_test.rb
CHANGED
@@ -5,10 +5,9 @@ require 'fixtures/company'
|
|
5
5
|
require 'fixtures/company_in_module'
|
6
6
|
|
7
7
|
class ReflectionTest < Test::Unit::TestCase
|
8
|
+
fixtures :topics, :customers, :companies
|
9
|
+
|
8
10
|
def setup
|
9
|
-
@topics = create_fixtures "topics"
|
10
|
-
@customers = create_fixtures "customers"
|
11
|
-
@companies = create_fixtures "companies"
|
12
11
|
@first = Topic.find(1)
|
13
12
|
end
|
14
13
|
|
@@ -23,6 +22,11 @@ class ReflectionTest < Test::Unit::TestCase
|
|
23
22
|
assert_equal 12, Topic.columns.length
|
24
23
|
end
|
25
24
|
|
25
|
+
def test_columns_are_returned_in_the_order_they_were_declared
|
26
|
+
column_names = Topic.columns.map { |column| column.name }
|
27
|
+
assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id type), column_names
|
28
|
+
end
|
29
|
+
|
26
30
|
def test_content_columns
|
27
31
|
assert_equal 8, Topic.content_columns.length
|
28
32
|
end
|
@@ -78,4 +82,4 @@ class ReflectionTest < Test::Unit::TestCase
|
|
78
82
|
assert_equal MyApplication::Business::Client, MyApplication::Business::Firm.reflect_on_association(:clients_of_firm).klass
|
79
83
|
assert_equal MyApplication::Business::Firm, MyApplication::Billing::Account.reflect_on_association(:firm).klass
|
80
84
|
end
|
81
|
-
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
|
3
|
+
class SchemaTest < Test::Unit::TestCase
|
4
|
+
SCHEMA_NAME = 'test_schema'
|
5
|
+
TABLE_NAME = 'things'
|
6
|
+
COLUMNS = [
|
7
|
+
'id integer',
|
8
|
+
'name character varying(50)',
|
9
|
+
'moment timestamp without time zone default now()'
|
10
|
+
]
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@connection = ActiveRecord::Base.connection
|
14
|
+
@connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
@connection.execute "DROP TABLE #{SCHEMA_NAME}.#{TABLE_NAME}"
|
19
|
+
@connection.execute "DROP SCHEMA #{SCHEMA_NAME}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_with_schema_prefixed_table_name
|
23
|
+
assert_nothing_raised do
|
24
|
+
assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{TABLE_NAME}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_with_schema_search_path
|
29
|
+
assert_nothing_raised do
|
30
|
+
with_schema_search_path(SCHEMA_NAME) do
|
31
|
+
assert_equal COLUMNS, columns(TABLE_NAME)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_raise_on_unquoted_schema_name
|
37
|
+
assert_raise(ActiveRecord::StatementInvalid) do
|
38
|
+
with_schema_search_path '$user,public'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_without_schema_search_path
|
43
|
+
assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_ignore_nil_schema_search_path
|
47
|
+
assert_nothing_raised { with_schema_search_path nil }
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def columns(table_name)
|
52
|
+
@connection.send(:column_definitions, table_name).map do |name, type, default|
|
53
|
+
"#{name} #{type}" + (default ? " default #{default}" : '')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def with_schema_search_path(schema_search_path)
|
58
|
+
@connection.schema_search_path = schema_search_path
|
59
|
+
yield if block_given?
|
60
|
+
ensure
|
61
|
+
@connection.schema_search_path = "'$user', public"
|
62
|
+
end
|
63
|
+
end
|
data/test/thread_safety_test.rb
CHANGED
data/test/transactions_test.rb
CHANGED
@@ -3,9 +3,14 @@ require 'fixtures/topic'
|
|
3
3
|
|
4
4
|
|
5
5
|
class TransactionTest < Test::Unit::TestCase
|
6
|
+
self.use_transactional_fixtures = false
|
7
|
+
|
8
|
+
fixtures :topics
|
9
|
+
|
6
10
|
def setup
|
7
|
-
|
8
|
-
|
11
|
+
# sqlite does not seem to return these in the right order, so we sort them
|
12
|
+
# explicitly for sqlite's sake. sqlite3 does fine.
|
13
|
+
@first, @second = Topic.find(1, 2).sort_by { |t| t.id }
|
9
14
|
end
|
10
15
|
|
11
16
|
def test_successful
|
@@ -53,6 +58,8 @@ class TransactionTest < Test::Unit::TestCase
|
|
53
58
|
end
|
54
59
|
|
55
60
|
def test_failing_with_object_rollback
|
61
|
+
assert !@first.approved?, "First should be unapproved initially"
|
62
|
+
|
56
63
|
begin
|
57
64
|
Topic.transaction(@first, @second) do
|
58
65
|
@first.approved = true
|
data/test/unconnected_test.rb
CHANGED
data/test/validations_test.rb
CHANGED
@@ -3,6 +3,17 @@ require 'fixtures/topic'
|
|
3
3
|
require 'fixtures/reply'
|
4
4
|
require 'fixtures/developer'
|
5
5
|
|
6
|
+
# The following methods in Topic are used in test_conditional_validation_*
|
7
|
+
class Topic
|
8
|
+
def condition_is_true
|
9
|
+
return true
|
10
|
+
end
|
11
|
+
|
12
|
+
def condition_is_true_but_its_not
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
6
17
|
class ValidationsTest < Test::Unit::TestCase
|
7
18
|
fixtures :topics, :developers
|
8
19
|
|
@@ -210,11 +221,16 @@ class ValidationsTest < Test::Unit::TestCase
|
|
210
221
|
|
211
222
|
t = Topic.create
|
212
223
|
assert !t.save
|
213
|
-
assert_equal "can't be
|
214
|
-
assert_equal "can't be
|
224
|
+
assert_equal "can't be blank", t.errors.on(:title)
|
225
|
+
assert_equal "can't be blank", t.errors.on(:content)
|
215
226
|
|
216
227
|
t.title = "something"
|
217
|
-
t.content = "
|
228
|
+
t.content = " "
|
229
|
+
|
230
|
+
assert !t.save
|
231
|
+
assert_equal "can't be blank", t.errors.on(:content)
|
232
|
+
|
233
|
+
t.content = "like stuff"
|
218
234
|
|
219
235
|
assert t.save
|
220
236
|
end
|
@@ -303,6 +319,20 @@ class ValidationsTest < Test::Unit::TestCase
|
|
303
319
|
assert Topic.create("title" => nil, "content" => "abc").valid?
|
304
320
|
end
|
305
321
|
|
322
|
+
def test_numericality_with_allow_nil_and_getter_method
|
323
|
+
Developer.validates_numericality_of( :salary, :allow_nil => true)
|
324
|
+
developer = Developer.new("name" => "michael", "salary" => nil)
|
325
|
+
developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end")
|
326
|
+
assert developer.valid?
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_validates_exclusion_of
|
330
|
+
Topic.validates_exclusion_of( :title, :in => %w( abe monkey ) )
|
331
|
+
|
332
|
+
assert Topic.create("title" => "something", "content" => "abc").valid?
|
333
|
+
assert !Topic.create("title" => "monkey", "content" => "abc").valid?
|
334
|
+
end
|
335
|
+
|
306
336
|
def test_validates_length_of_using_minimum
|
307
337
|
Topic.validates_length_of :title, :minimum => 5
|
308
338
|
|
@@ -387,6 +417,48 @@ class ValidationsTest < Test::Unit::TestCase
|
|
387
417
|
assert t.valid?
|
388
418
|
end
|
389
419
|
|
420
|
+
def test_optionally_validates_length_of_using_within_on_create
|
421
|
+
Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: %d"
|
422
|
+
|
423
|
+
t = Topic.create("title" => "thisisnotvalid", "content" => "whatever")
|
424
|
+
assert !t.save
|
425
|
+
assert t.errors.on(:title)
|
426
|
+
assert_equal "my string is too long: 10", t.errors[:title]
|
427
|
+
|
428
|
+
t.title = "butthisis"
|
429
|
+
assert t.save
|
430
|
+
|
431
|
+
t.title = "few"
|
432
|
+
assert t.save
|
433
|
+
|
434
|
+
t.content = "andthisislong"
|
435
|
+
assert t.save
|
436
|
+
|
437
|
+
t.content = t.title = "iamfine"
|
438
|
+
assert t.save
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_optionally_validates_length_of_using_within_on_update
|
442
|
+
Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: %d"
|
443
|
+
|
444
|
+
t = Topic.create("title" => "vali", "content" => "whatever")
|
445
|
+
assert !t.save
|
446
|
+
assert t.errors.on(:title)
|
447
|
+
|
448
|
+
t.title = "not"
|
449
|
+
assert !t.save
|
450
|
+
assert t.errors.on(:title)
|
451
|
+
assert_equal "my string is too short: 5", t.errors[:title]
|
452
|
+
|
453
|
+
t.title = "valid"
|
454
|
+
t.content = "andthisistoolong"
|
455
|
+
assert !t.save
|
456
|
+
assert t.errors.on(:content)
|
457
|
+
|
458
|
+
t.content = "iamfine"
|
459
|
+
assert t.save
|
460
|
+
end
|
461
|
+
|
390
462
|
def test_validates_length_of_using_is
|
391
463
|
Topic.validates_length_of :title, :is => 5
|
392
464
|
|
@@ -428,6 +500,15 @@ class ValidationsTest < Test::Unit::TestCase
|
|
428
500
|
end
|
429
501
|
end
|
430
502
|
|
503
|
+
def test_validates_length_with_globaly_modified_error_message
|
504
|
+
ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre %d'
|
505
|
+
Topic.validates_length_of :title, :minimum => 10
|
506
|
+
t = Topic.create(:title => 'too short')
|
507
|
+
assert !t.valid?
|
508
|
+
|
509
|
+
assert_equal 'tu est trops petit hombre 10', t.errors['title']
|
510
|
+
end
|
511
|
+
|
431
512
|
def test_validates_size_of_association
|
432
513
|
assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 }
|
433
514
|
t = Topic.new('title' => 'noreplies', 'content' => 'whatever')
|
@@ -633,13 +714,13 @@ class ValidationsTest < Test::Unit::TestCase
|
|
633
714
|
def test_validates_numericality_of
|
634
715
|
Topic.validates_numericality_of( :approved, :allow_nil => true )
|
635
716
|
["10", "10.0", "10.5", "-10.5", "-0.0001","0090","-090","-090.1",nil,""].each do |v|
|
636
|
-
t = Topic.
|
717
|
+
t = Topic.new("title" => "numeric test", "content" => "whatever", "approved" => v)
|
637
718
|
assert t.valid?, "#{v} not recognized as a number"
|
638
719
|
# we cannot check this as approved is actually an integer field
|
639
720
|
#assert_in_delta v.to_f, t.approved, 0.0000001
|
640
721
|
end
|
641
722
|
end
|
642
|
-
|
723
|
+
|
643
724
|
def test_validates_numericality_of_int_with_string
|
644
725
|
Topic.validates_numericality_of( :approved, :only_integer => true )
|
645
726
|
["not a number","42 not a number","0xdeadbeef","0-1","--3","+-3","+3-1",nil].each do |v|
|
@@ -648,14 +729,76 @@ class ValidationsTest < Test::Unit::TestCase
|
|
648
729
|
assert t.errors.on(:approved)
|
649
730
|
end
|
650
731
|
end
|
651
|
-
|
732
|
+
|
652
733
|
def test_validates_numericality_of_int
|
653
734
|
Topic.validates_numericality_of( :approved, :only_integer => true, :allow_nil => true )
|
654
735
|
["42", "+42", "-42", "042", "0042", "-042", 42, nil,""].each do |v|
|
655
|
-
t = Topic.
|
736
|
+
t = Topic.new("title" => "numeric test", "content" => "whatever", "approved" => v)
|
656
737
|
assert t.valid?, "#{v} not recognized as integer"
|
657
738
|
assert_equal((v.nil? or v == "")? nil : v.to_i, t.approved)
|
658
739
|
end
|
659
740
|
end
|
660
741
|
|
661
|
-
|
742
|
+
def test_conditional_validation_using_method_true
|
743
|
+
# When the method returns true
|
744
|
+
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true )
|
745
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
746
|
+
assert !t.valid?
|
747
|
+
assert t.errors.on(:title)
|
748
|
+
assert_equal "hoo 5", t.errors["title"]
|
749
|
+
end
|
750
|
+
|
751
|
+
def test_conditional_validation_using_method_false
|
752
|
+
# When the method returns false
|
753
|
+
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not )
|
754
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
755
|
+
assert t.valid?
|
756
|
+
assert !t.errors.on(:title)
|
757
|
+
end
|
758
|
+
|
759
|
+
def test_conditional_validation_using_string_true
|
760
|
+
# When the evaluated string returns true
|
761
|
+
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" )
|
762
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
763
|
+
assert !t.valid?
|
764
|
+
assert t.errors.on(:title)
|
765
|
+
assert_equal "hoo 5", t.errors["title"]
|
766
|
+
end
|
767
|
+
|
768
|
+
def test_conditional_validation_using_string_false
|
769
|
+
# When the evaluated string returns false
|
770
|
+
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false")
|
771
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
772
|
+
assert t.valid?
|
773
|
+
assert !t.errors.on(:title)
|
774
|
+
end
|
775
|
+
|
776
|
+
def test_conditional_validation_using_block_true
|
777
|
+
# When the block returns true
|
778
|
+
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
|
779
|
+
:if => Proc.new { |r| r.content.size > 4 } )
|
780
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
781
|
+
assert !t.valid?
|
782
|
+
assert t.errors.on(:title)
|
783
|
+
assert_equal "hoo 5", t.errors["title"]
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_conditional_validation_using_block_false
|
787
|
+
# When the block returns false
|
788
|
+
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
|
789
|
+
:if => Proc.new { |r| r.title != "uhohuhoh"} )
|
790
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
791
|
+
assert t.valid?
|
792
|
+
assert !t.errors.on(:title)
|
793
|
+
end
|
794
|
+
|
795
|
+
def test_validates_associated_missing
|
796
|
+
Reply.validates_presence_of(:topic)
|
797
|
+
r = Reply.create("title" => "A reply", "content" => "with content!")
|
798
|
+
assert !r.valid?
|
799
|
+
assert r.errors.on(:topic)
|
800
|
+
|
801
|
+
r.topic = Topic.find :first
|
802
|
+
assert r.valid?
|
803
|
+
end
|
804
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.10
|
3
3
|
specification_version: 1
|
4
4
|
name: activerecord
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2005-
|
6
|
+
version: 1.11.0
|
7
|
+
date: 2005-07-06
|
8
8
|
summary: Implements the ActiveRecord pattern for ORM.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- lib/active_record/locking.rb
|
50
50
|
- lib/active_record/migration.rb
|
51
51
|
- lib/active_record/observer.rb
|
52
|
+
- lib/active_record/query_cache.rb
|
52
53
|
- lib/active_record/reflection.rb
|
53
54
|
- lib/active_record/timestamp.rb
|
54
55
|
- lib/active_record/transactions.rb
|
@@ -82,6 +83,7 @@ files:
|
|
82
83
|
- test/active_schema_mysql.rb
|
83
84
|
- test/aggregations_test.rb
|
84
85
|
- test/all.sh
|
86
|
+
- test/association_callbacks_test.rb
|
85
87
|
- test/association_inheritance_reload.rb
|
86
88
|
- test/associations_go_eager_test.rb
|
87
89
|
- test/associations_test.rb
|
@@ -99,13 +101,14 @@ files:
|
|
99
101
|
- test/inheritance_test.rb
|
100
102
|
- test/lifecycle_test.rb
|
101
103
|
- test/locking_test.rb
|
102
|
-
- test/
|
104
|
+
- test/migration_test.rb
|
103
105
|
- test/mixin_nested_set_test.rb
|
104
106
|
- test/mixin_test.rb
|
105
107
|
- test/modules_test.rb
|
106
108
|
- test/multiple_db_test.rb
|
107
109
|
- test/pk_test.rb
|
108
110
|
- test/reflection_test.rb
|
111
|
+
- test/schema_test_postgresql.rb
|
109
112
|
- test/thread_safety_test.rb
|
110
113
|
- test/transactions_test.rb
|
111
114
|
- test/unconnected_test.rb
|
@@ -117,6 +120,7 @@ files:
|
|
117
120
|
- test/connections/native_sqlite
|
118
121
|
- test/connections/native_sqlite3
|
119
122
|
- test/connections/native_sqlserver
|
123
|
+
- test/connections/native_sqlserver_odbc
|
120
124
|
- test/connections/native_db2/connection.rb
|
121
125
|
- test/connections/native_mysql/connection.rb
|
122
126
|
- test/connections/native_oci/connection.rb
|
@@ -124,6 +128,7 @@ files:
|
|
124
128
|
- test/connections/native_sqlite/connection.rb
|
125
129
|
- test/connections/native_sqlite3/connection.rb
|
126
130
|
- test/connections/native_sqlserver/connection.rb
|
131
|
+
- test/connections/native_sqlserver_odbc/connection.rb
|
127
132
|
- test/fixtures/accounts.yml
|
128
133
|
- test/fixtures/associations.png
|
129
134
|
- test/fixtures/author.rb
|
@@ -211,6 +216,7 @@ files:
|
|
211
216
|
- test/fixtures/developers_projects/jamis_active_record
|
212
217
|
- test/fixtures/migrations/1_people_have_last_names.rb
|
213
218
|
- test/fixtures/migrations/2_we_need_reminders.rb
|
219
|
+
- test/fixtures/migrations/3_innocent_jointable.rb
|
214
220
|
- test/fixtures/naked/csv
|
215
221
|
- test/fixtures/naked/yml
|
216
222
|
- test/fixtures/naked/csv/accounts.csv
|
@@ -241,5 +247,5 @@ dependencies:
|
|
241
247
|
-
|
242
248
|
- "="
|
243
249
|
- !ruby/object:Gem::Version
|
244
|
-
version: 1.0
|
250
|
+
version: 1.1.0
|
245
251
|
version:
|