activerecord 2.0.2 → 2.0.4
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 +25 -0
- data/README +0 -0
- data/Rakefile +5 -3
- data/lib/active_record.rb +0 -0
- data/lib/active_record/associations.rb +232 -193
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +14 -14
- data/lib/active_record/associations/has_many_association.rb +2 -2
- data/lib/active_record/associations/has_many_through_association.rb +25 -6
- data/lib/active_record/attribute_methods.rb +4 -3
- data/lib/active_record/base.rb +75 -41
- data/lib/active_record/calculations.rb +2 -1
- data/lib/active_record/callbacks.rb +0 -0
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +8 -6
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +12 -11
- data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -6
- data/lib/active_record/fixtures.rb +29 -31
- data/lib/active_record/migration.rb +4 -5
- data/lib/active_record/observer.rb +1 -1
- data/lib/active_record/transactions.rb +3 -5
- data/lib/active_record/validations.rb +5 -3
- data/lib/active_record/version.rb +1 -1
- data/test/abstract_unit.rb +0 -0
- data/test/active_schema_test_mysql.rb +5 -2
- data/test/adapter_test.rb +1 -0
- data/test/all.sh +0 -0
- data/test/associations/callbacks_test.rb +1 -1
- data/test/associations/eager_test.rb +5 -0
- data/test/associations/join_model_test.rb +11 -3
- data/test/associations_test.rb +36 -6
- data/test/attribute_methods_test.rb +0 -0
- data/test/base_test.rb +92 -10
- data/test/calculations_test.rb +9 -1
- data/test/debug.log +358 -0
- data/test/deprecated_finder_test.rb +0 -0
- data/test/fixtures/author.rb +1 -1
- data/test/fixtures/company.rb +0 -0
- data/test/fixtures/fixture_database.sqlite3 +0 -0
- data/test/fixtures/fixture_database_2.sqlite3 +0 -0
- data/test/fixtures/reply.rb +0 -0
- data/test/fixtures/topic.rb +0 -0
- data/test/fixtures_test.rb +20 -12
- data/test/inheritance_test.rb +0 -0
- data/test/lifecycle_test.rb +0 -0
- data/test/migration_test.rb +46 -0
- data/test/query_cache_test.rb +22 -2
- data/test/readonly_test.rb +0 -0
- data/test/unconnected_test.rb +0 -0
- data/test/validations_test.rb +50 -38
- metadata +8 -4
File without changes
|
data/test/fixtures/author.rb
CHANGED
data/test/fixtures/company.rb
CHANGED
File without changes
|
Binary file
|
Binary file
|
data/test/fixtures/reply.rb
CHANGED
File without changes
|
data/test/fixtures/topic.rb
CHANGED
File without changes
|
data/test/fixtures_test.rb
CHANGED
@@ -324,21 +324,29 @@ class MultipleFixturesTest < Test::Unit::TestCase
|
|
324
324
|
end
|
325
325
|
end
|
326
326
|
|
327
|
-
|
328
|
-
#
|
329
|
-
|
330
|
-
|
331
|
-
|
327
|
+
class SetupTest < Test::Unit::TestCase
|
328
|
+
# fixtures :topics
|
329
|
+
|
330
|
+
def setup
|
331
|
+
@first = true
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_nothing
|
335
|
+
end
|
336
|
+
end
|
332
337
|
|
333
|
-
|
334
|
-
|
338
|
+
class SetupSubclassTest < SetupTest
|
339
|
+
def setup
|
340
|
+
super
|
341
|
+
@second = true
|
342
|
+
end
|
335
343
|
|
336
|
-
|
337
|
-
|
338
|
-
|
344
|
+
def test_subclassing_should_preserve_setups
|
345
|
+
assert @first
|
346
|
+
assert @second
|
339
347
|
end
|
340
|
-
|
341
|
-
|
348
|
+
end
|
349
|
+
|
342
350
|
|
343
351
|
class OverlappingFixturesTest < Test::Unit::TestCase
|
344
352
|
fixtures :topics, :developers
|
data/test/inheritance_test.rb
CHANGED
File without changes
|
data/test/lifecycle_test.rb
CHANGED
File without changes
|
data/test/migration_test.rb
CHANGED
@@ -431,6 +431,44 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
431
431
|
end
|
432
432
|
end
|
433
433
|
|
434
|
+
def test_rename_column_with_an_index
|
435
|
+
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
436
|
+
table.column :hat_name, :string, :limit => 100
|
437
|
+
table.column :hat_size, :integer
|
438
|
+
end
|
439
|
+
Person.connection.add_index :people, :first_name
|
440
|
+
assert_nothing_raised do
|
441
|
+
Person.connection.rename_column "hats", "hat_name", "name"
|
442
|
+
end
|
443
|
+
ensure
|
444
|
+
ActiveRecord::Base.connection.drop_table(:hats)
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_remove_column_with_index
|
448
|
+
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
449
|
+
table.column :hat_name, :string, :limit => 100
|
450
|
+
table.column :hat_size, :integer
|
451
|
+
end
|
452
|
+
ActiveRecord::Base.connection.add_index "hats", "hat_size"
|
453
|
+
|
454
|
+
assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
|
455
|
+
ensure
|
456
|
+
ActiveRecord::Base.connection.drop_table(:hats)
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_remove_column_with_multi_column_index
|
460
|
+
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
461
|
+
table.column :hat_name, :string, :limit => 100
|
462
|
+
table.column :hat_size, :integer
|
463
|
+
table.column :hat_style, :string, :limit => 100
|
464
|
+
end
|
465
|
+
ActiveRecord::Base.connection.add_index "hats", ["hat_style", "hat_size"], :unique => true
|
466
|
+
|
467
|
+
assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
|
468
|
+
ensure
|
469
|
+
ActiveRecord::Base.connection.drop_table(:hats)
|
470
|
+
end
|
471
|
+
|
434
472
|
def test_change_type_of_not_null_column
|
435
473
|
assert_nothing_raised do
|
436
474
|
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
|
@@ -887,6 +925,14 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
887
925
|
end
|
888
926
|
end
|
889
927
|
|
928
|
+
def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
|
929
|
+
with_new_table do |t|
|
930
|
+
t.expects(:column).with('taggable_type', :string, {:null => false})
|
931
|
+
t.expects(:column).with('taggable_id', :integer, {:null => false})
|
932
|
+
t.references :taggable, :polymorphic => true, :null => false
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
890
936
|
def test_belongs_to_works_like_references
|
891
937
|
with_new_table do |t|
|
892
938
|
t.expects(:column).with('customer_id', :integer, {})
|
data/test/query_cache_test.rb
CHANGED
@@ -3,10 +3,12 @@ require 'fixtures/topic'
|
|
3
3
|
require 'fixtures/reply'
|
4
4
|
require 'fixtures/task'
|
5
5
|
require 'fixtures/course'
|
6
|
+
require 'fixtures/category'
|
7
|
+
require 'fixtures/post'
|
6
8
|
|
7
9
|
|
8
|
-
class QueryCacheTest <
|
9
|
-
fixtures :tasks, :topics
|
10
|
+
class QueryCacheTest < ActiveSupport::TestCase
|
11
|
+
fixtures :tasks, :topics, :categories, :posts, :categories_posts
|
10
12
|
|
11
13
|
def test_find_queries
|
12
14
|
assert_queries(2) { Task.find(1); Task.find(1) }
|
@@ -99,6 +101,24 @@ class QueryCacheExpiryTest < Test::Unit::TestCase
|
|
99
101
|
Task.create!
|
100
102
|
end
|
101
103
|
end
|
104
|
+
|
105
|
+
def test_cache_is_expired_by_habtm_update
|
106
|
+
ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
|
107
|
+
ActiveRecord::Base.cache do
|
108
|
+
c = Category.find(:first)
|
109
|
+
p = Post.find(:first)
|
110
|
+
p.categories << c
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_cache_is_expired_by_habtm_delete
|
115
|
+
ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
|
116
|
+
ActiveRecord::Base.cache do
|
117
|
+
c = Category.find(:first)
|
118
|
+
p = Post.find(:first)
|
119
|
+
p.categories.delete_all
|
120
|
+
end
|
121
|
+
end
|
102
122
|
end
|
103
123
|
|
104
124
|
end
|
data/test/readonly_test.rb
CHANGED
File without changes
|
data/test/unconnected_test.rb
CHANGED
File without changes
|
data/test/validations_test.rb
CHANGED
@@ -150,7 +150,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
150
150
|
|
151
151
|
def test_create_with_exceptions_using_scope_and_empty_attributes
|
152
152
|
assert_nothing_raised do
|
153
|
-
ProtectedPerson.with_scope( :create => { :first_name => "Mary" } ) do
|
153
|
+
ProtectedPerson.with_scope( :create => { :first_name => "Mary" } ) do
|
154
154
|
person = ProtectedPerson.create!
|
155
155
|
assert_equal person.first_name, "Mary", "should be ok when no attributes are passed to create!"
|
156
156
|
end
|
@@ -301,13 +301,13 @@ class ValidationsTest < Test::Unit::TestCase
|
|
301
301
|
assert_equal "Dan Brown", reply["author_name"]
|
302
302
|
end
|
303
303
|
|
304
|
-
def test_validates_acceptance_of_with_non_existant_table
|
305
|
-
Object.const_set :IncorporealModel, Class.new(ActiveRecord::Base)
|
306
|
-
|
307
|
-
assert_nothing_raised ActiveRecord::StatementInvalid do
|
308
|
-
IncorporealModel.validates_acceptance_of(:incorporeal_column)
|
309
|
-
end
|
310
|
-
end
|
304
|
+
def test_validates_acceptance_of_with_non_existant_table
|
305
|
+
Object.const_set :IncorporealModel, Class.new(ActiveRecord::Base)
|
306
|
+
|
307
|
+
assert_nothing_raised ActiveRecord::StatementInvalid do
|
308
|
+
IncorporealModel.validates_acceptance_of(:incorporeal_column)
|
309
|
+
end
|
310
|
+
end
|
311
311
|
|
312
312
|
def test_validate_presences
|
313
313
|
Topic.validates_presence_of(:title, :content)
|
@@ -384,22 +384,22 @@ class ValidationsTest < Test::Unit::TestCase
|
|
384
384
|
Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
|
385
385
|
|
386
386
|
t = Topic.create("title" => "The earth is actually flat!")
|
387
|
-
|
387
|
+
|
388
388
|
r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
|
389
389
|
assert r1.valid?, "Saving r1"
|
390
|
-
|
390
|
+
|
391
391
|
r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
|
392
|
-
assert !r2.valid?, "Saving r2. Double reply by same author."
|
393
|
-
|
392
|
+
assert !r2.valid?, "Saving r2. Double reply by same author."
|
393
|
+
|
394
394
|
r2.author_email_address = "jeremy_alt_email@rubyonrails.com"
|
395
|
-
assert r2.save, "Saving r2 the second time."
|
396
|
-
|
395
|
+
assert r2.save, "Saving r2 the second time."
|
396
|
+
|
397
397
|
r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
|
398
398
|
assert !r3.valid?, "Saving r3"
|
399
|
-
|
399
|
+
|
400
400
|
r3.author_name = "jj"
|
401
401
|
assert r3.save, "Saving r3 the second time."
|
402
|
-
|
402
|
+
|
403
403
|
r3.author_name = "jeremy"
|
404
404
|
assert !r3.save, "Saving r3 the third time."
|
405
405
|
end
|
@@ -480,7 +480,15 @@ class ValidationsTest < Test::Unit::TestCase
|
|
480
480
|
|
481
481
|
assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) }
|
482
482
|
end
|
483
|
-
|
483
|
+
|
484
|
+
def test_validate_format_with_allow_blank
|
485
|
+
Topic.validates_format_of(:title, :with => /^Validation\smacros \w+!$/, :allow_blank=>true)
|
486
|
+
assert !Topic.create("title" => "Shouldn't be valid").valid?
|
487
|
+
assert Topic.create("title" => "").valid?
|
488
|
+
assert Topic.create("title" => nil).valid?
|
489
|
+
assert Topic.create("title" => "Validation macros rule!").valid?
|
490
|
+
end
|
491
|
+
|
484
492
|
# testing ticket #3142
|
485
493
|
def test_validate_format_numeric
|
486
494
|
Topic.validates_format_of(:title, :content, :with => /^[1-9][0-9]*$/, :message => "is bad data")
|
@@ -849,18 +857,8 @@ class ValidationsTest < Test::Unit::TestCase
|
|
849
857
|
assert_equal "hoo 5", t.errors["title"]
|
850
858
|
end
|
851
859
|
|
852
|
-
def kcode_scope(kcode)
|
853
|
-
orig_kcode = $KCODE
|
854
|
-
$KCODE = kcode
|
855
|
-
begin
|
856
|
-
yield
|
857
|
-
ensure
|
858
|
-
$KCODE = orig_kcode
|
859
|
-
end
|
860
|
-
end
|
861
|
-
|
862
860
|
def test_validates_length_of_using_minimum_utf8
|
863
|
-
|
861
|
+
with_kcode('UTF8') do
|
864
862
|
Topic.validates_length_of :title, :minimum => 5
|
865
863
|
|
866
864
|
t = Topic.create("title" => "一二三四五", "content" => "whatever")
|
@@ -874,7 +872,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
874
872
|
end
|
875
873
|
|
876
874
|
def test_validates_length_of_using_maximum_utf8
|
877
|
-
|
875
|
+
with_kcode('UTF8') do
|
878
876
|
Topic.validates_length_of :title, :maximum => 5
|
879
877
|
|
880
878
|
t = Topic.create("title" => "一二三四五", "content" => "whatever")
|
@@ -888,7 +886,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
888
886
|
end
|
889
887
|
|
890
888
|
def test_validates_length_of_using_within_utf8
|
891
|
-
|
889
|
+
with_kcode('UTF8') do
|
892
890
|
Topic.validates_length_of(:title, :content, :within => 3..5)
|
893
891
|
|
894
892
|
t = Topic.new("title" => "一二", "content" => "12三四五六七")
|
@@ -902,7 +900,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
902
900
|
end
|
903
901
|
|
904
902
|
def test_optionally_validates_length_of_using_within_utf8
|
905
|
-
|
903
|
+
with_kcode('UTF8') do
|
906
904
|
Topic.validates_length_of :title, :content, :within => 3..5, :allow_nil => true
|
907
905
|
|
908
906
|
t = Topic.create('title' => '一二三', 'content' => '一二三四五')
|
@@ -914,7 +912,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
914
912
|
end
|
915
913
|
|
916
914
|
def test_optionally_validates_length_of_using_within_on_create_utf8
|
917
|
-
|
915
|
+
with_kcode('UTF8') do
|
918
916
|
Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "長すぎます: %d"
|
919
917
|
|
920
918
|
t = Topic.create("title" => "一二三四五六七八九十A", "content" => "whatever")
|
@@ -937,7 +935,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
937
935
|
end
|
938
936
|
|
939
937
|
def test_optionally_validates_length_of_using_within_on_update_utf8
|
940
|
-
|
938
|
+
with_kcode('UTF8') do
|
941
939
|
Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "短すぎます: %d"
|
942
940
|
|
943
941
|
t = Topic.create("title" => "一二三4", "content" => "whatever")
|
@@ -960,7 +958,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
960
958
|
end
|
961
959
|
|
962
960
|
def test_validates_length_of_using_is_utf8
|
963
|
-
|
961
|
+
with_kcode('UTF8') do
|
964
962
|
Topic.validates_length_of :title, :is => 5
|
965
963
|
|
966
964
|
t = Topic.create("title" => "一二345", "content" => "whatever")
|
@@ -974,7 +972,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
974
972
|
end
|
975
973
|
|
976
974
|
def test_validates_size_of_association_utf8
|
977
|
-
|
975
|
+
with_kcode('UTF8') do
|
978
976
|
assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 }
|
979
977
|
t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ')
|
980
978
|
assert !t.save
|
@@ -1222,7 +1220,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
1222
1220
|
r = Reply.create("title" => "A reply", "content" => "with content!")
|
1223
1221
|
assert !r.valid?
|
1224
1222
|
assert r.errors.on(:topic)
|
1225
|
-
|
1223
|
+
|
1226
1224
|
r.topic = Topic.find :first
|
1227
1225
|
assert r.valid?
|
1228
1226
|
end
|
@@ -1245,8 +1243,8 @@ class ValidationsTest < Test::Unit::TestCase
|
|
1245
1243
|
assert_equal "can't be blank", t.errors.on("title").first
|
1246
1244
|
end
|
1247
1245
|
|
1248
|
-
# previous implementation of validates_presence_of eval'd the
|
1249
|
-
# string with the wrong binding, this regression test is to
|
1246
|
+
# previous implementation of validates_presence_of eval'd the
|
1247
|
+
# string with the wrong binding, this regression test is to
|
1250
1248
|
# ensure that it works correctly
|
1251
1249
|
def test_validation_with_if_as_string
|
1252
1250
|
Topic.validates_presence_of(:title)
|
@@ -1266,6 +1264,20 @@ class ValidationsTest < Test::Unit::TestCase
|
|
1266
1264
|
t.author_name = "Hubert J. Farnsworth"
|
1267
1265
|
assert t.valid?, "A topic with an important title and author should be valid"
|
1268
1266
|
end
|
1267
|
+
|
1268
|
+
private
|
1269
|
+
def with_kcode(kcode)
|
1270
|
+
if RUBY_VERSION < '1.9'
|
1271
|
+
orig_kcode, $KCODE = $KCODE, kcode
|
1272
|
+
begin
|
1273
|
+
yield
|
1274
|
+
ensure
|
1275
|
+
$KCODE = orig_kcode
|
1276
|
+
end
|
1277
|
+
else
|
1278
|
+
yield
|
1279
|
+
end
|
1280
|
+
end
|
1269
1281
|
end
|
1270
1282
|
|
1271
1283
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
@@ -9,17 +9,18 @@ autorequire: active_record
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2008-09-03 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - "="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: 2.0.
|
23
|
+
version: 2.0.4
|
23
24
|
version:
|
24
25
|
description: Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database tables and classes together for business objects, like Customer or Subscription, that can find, save, and destroy themselves without resorting to manual SQL.
|
25
26
|
email: david@loudthinking.com
|
@@ -139,6 +140,7 @@ files:
|
|
139
140
|
- test/copy_table_test_sqlite.rb
|
140
141
|
- test/datatype_test_postgresql.rb
|
141
142
|
- test/date_time_test.rb
|
143
|
+
- test/debug.log
|
142
144
|
- test/default_test_firebird.rb
|
143
145
|
- test/defaults_test.rb
|
144
146
|
- test/deprecated_finder_test.rb
|
@@ -235,6 +237,8 @@ files:
|
|
235
237
|
- test/fixtures/entrant.rb
|
236
238
|
- test/fixtures/entrants.yml
|
237
239
|
- test/fixtures/example.log
|
240
|
+
- test/fixtures/fixture_database.sqlite3
|
241
|
+
- test/fixtures/fixture_database_2.sqlite3
|
238
242
|
- test/fixtures/fk_test_has_fk.yml
|
239
243
|
- test/fixtures/fk_test_has_pk.yml
|
240
244
|
- test/fixtures/flowers.jpg
|
@@ -368,7 +372,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
368
372
|
requirements: []
|
369
373
|
|
370
374
|
rubyforge_project: activerecord
|
371
|
-
rubygems_version: 1.
|
375
|
+
rubygems_version: 1.2.0
|
372
376
|
signing_key:
|
373
377
|
specification_version: 2
|
374
378
|
summary: Implements the ActiveRecord pattern for ORM.
|