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.

Files changed (53) hide show
  1. data/CHANGELOG +25 -0
  2. data/README +0 -0
  3. data/Rakefile +5 -3
  4. data/lib/active_record.rb +0 -0
  5. data/lib/active_record/associations.rb +232 -193
  6. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +14 -14
  7. data/lib/active_record/associations/has_many_association.rb +2 -2
  8. data/lib/active_record/associations/has_many_through_association.rb +25 -6
  9. data/lib/active_record/attribute_methods.rb +4 -3
  10. data/lib/active_record/base.rb +75 -41
  11. data/lib/active_record/calculations.rb +2 -1
  12. data/lib/active_record/callbacks.rb +0 -0
  13. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +1 -1
  14. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +8 -6
  15. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +12 -11
  16. data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -0
  18. data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
  19. data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -6
  20. data/lib/active_record/fixtures.rb +29 -31
  21. data/lib/active_record/migration.rb +4 -5
  22. data/lib/active_record/observer.rb +1 -1
  23. data/lib/active_record/transactions.rb +3 -5
  24. data/lib/active_record/validations.rb +5 -3
  25. data/lib/active_record/version.rb +1 -1
  26. data/test/abstract_unit.rb +0 -0
  27. data/test/active_schema_test_mysql.rb +5 -2
  28. data/test/adapter_test.rb +1 -0
  29. data/test/all.sh +0 -0
  30. data/test/associations/callbacks_test.rb +1 -1
  31. data/test/associations/eager_test.rb +5 -0
  32. data/test/associations/join_model_test.rb +11 -3
  33. data/test/associations_test.rb +36 -6
  34. data/test/attribute_methods_test.rb +0 -0
  35. data/test/base_test.rb +92 -10
  36. data/test/calculations_test.rb +9 -1
  37. data/test/debug.log +358 -0
  38. data/test/deprecated_finder_test.rb +0 -0
  39. data/test/fixtures/author.rb +1 -1
  40. data/test/fixtures/company.rb +0 -0
  41. data/test/fixtures/fixture_database.sqlite3 +0 -0
  42. data/test/fixtures/fixture_database_2.sqlite3 +0 -0
  43. data/test/fixtures/reply.rb +0 -0
  44. data/test/fixtures/topic.rb +0 -0
  45. data/test/fixtures_test.rb +20 -12
  46. data/test/inheritance_test.rb +0 -0
  47. data/test/lifecycle_test.rb +0 -0
  48. data/test/migration_test.rb +46 -0
  49. data/test/query_cache_test.rb +22 -2
  50. data/test/readonly_test.rb +0 -0
  51. data/test/unconnected_test.rb +0 -0
  52. data/test/validations_test.rb +50 -38
  53. metadata +8 -4
File without changes
@@ -105,5 +105,5 @@ end
105
105
 
106
106
  class AuthorFavorite < ActiveRecord::Base
107
107
  belongs_to :author
108
- belongs_to :favorite_author, :class_name => "Author", :foreign_key => 'favorite_author_id'
108
+ belongs_to :favorite_author, :class_name => "Author"
109
109
  end
File without changes
File without changes
File without changes
@@ -324,21 +324,29 @@ class MultipleFixturesTest < Test::Unit::TestCase
324
324
  end
325
325
  end
326
326
 
327
- # This is to reproduce a bug where if a TestCase is loaded
328
- # twice by Ruby, it loses its fixture setup hook.
329
- class_def = <<-CODE
330
- class DoubleLoadedTestCase < Test::Unit::TestCase
331
- fixtures :topics
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
- def setup
334
- end
338
+ class SetupSubclassTest < SetupTest
339
+ def setup
340
+ super
341
+ @second = true
342
+ end
335
343
 
336
- def test_should_properly_setup_fixtures
337
- assert_nothing_raised { topics(:first) }
338
- end
344
+ def test_subclassing_should_preserve_setups
345
+ assert @first
346
+ assert @second
339
347
  end
340
- CODE
341
- 2.times { eval(class_def) }
348
+ end
349
+
342
350
 
343
351
  class OverlappingFixturesTest < Test::Unit::TestCase
344
352
  fixtures :topics, :developers
File without changes
File without changes
@@ -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, {})
@@ -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 < Test::Unit::TestCase
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
File without changes
File without changes
@@ -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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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
- kcode_scope('UTF8') do
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.2
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: 2007-12-20 00:00:00 -06:00
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.2
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.0.0
375
+ rubygems_version: 1.2.0
372
376
  signing_key:
373
377
  specification_version: 2
374
378
  summary: Implements the ActiveRecord pattern for ORM.