activerecord 1.4.0 → 1.5.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 (55) hide show
  1. data/CHANGELOG +98 -0
  2. data/install.rb +1 -0
  3. data/lib/active_record.rb +1 -0
  4. data/lib/active_record/acts/list.rb +19 -16
  5. data/lib/active_record/associations.rb +164 -164
  6. data/lib/active_record/associations/association_collection.rb +44 -71
  7. data/lib/active_record/associations/association_proxy.rb +76 -0
  8. data/lib/active_record/associations/belongs_to_association.rb +74 -0
  9. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +34 -21
  10. data/lib/active_record/associations/has_many_association.rb +34 -30
  11. data/lib/active_record/associations/has_one_association.rb +48 -0
  12. data/lib/active_record/base.rb +62 -18
  13. data/lib/active_record/callbacks.rb +17 -8
  14. data/lib/active_record/connection_adapters/abstract_adapter.rb +11 -10
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  16. data/lib/active_record/connection_adapters/postgresql_adapter.rb +29 -1
  17. data/lib/active_record/connection_adapters/sqlite_adapter.rb +94 -73
  18. data/lib/active_record/deprecated_associations.rb +46 -8
  19. data/lib/active_record/fixtures.rb +1 -1
  20. data/lib/active_record/observer.rb +5 -1
  21. data/lib/active_record/support/binding_of_caller.rb +72 -68
  22. data/lib/active_record/support/breakpoint.rb +526 -524
  23. data/lib/active_record/support/class_inheritable_attributes.rb +105 -29
  24. data/lib/active_record/support/core_ext.rb +1 -0
  25. data/lib/active_record/support/core_ext/hash.rb +5 -0
  26. data/lib/active_record/support/core_ext/hash/keys.rb +35 -0
  27. data/lib/active_record/support/core_ext/numeric.rb +7 -0
  28. data/lib/active_record/support/core_ext/numeric/bytes.rb +33 -0
  29. data/lib/active_record/support/core_ext/numeric/time.rb +59 -0
  30. data/lib/active_record/support/core_ext/string.rb +5 -0
  31. data/lib/active_record/support/core_ext/string/inflections.rb +41 -0
  32. data/lib/active_record/support/dependencies.rb +1 -14
  33. data/lib/active_record/support/inflector.rb +6 -6
  34. data/lib/active_record/support/misc.rb +0 -24
  35. data/lib/active_record/validations.rb +34 -1
  36. data/lib/active_record/vendor/mysql411.rb +305 -0
  37. data/rakefile +11 -2
  38. data/test/abstract_unit.rb +1 -2
  39. data/test/associations_test.rb +234 -23
  40. data/test/base_test.rb +50 -1
  41. data/test/callbacks_test.rb +16 -0
  42. data/test/connections/native_mysql/connection.rb +2 -2
  43. data/test/connections/native_sqlite3/connection.rb +34 -0
  44. data/test/deprecated_associations_test.rb +36 -2
  45. data/test/fixtures/company.rb +2 -0
  46. data/test/fixtures/computer.rb +3 -0
  47. data/test/fixtures/computers.yml +3 -0
  48. data/test/fixtures/db_definitions/db2.sql +5 -0
  49. data/test/fixtures/db_definitions/mysql.sql +5 -0
  50. data/test/fixtures/db_definitions/postgresql.sql +5 -0
  51. data/test/fixtures/db_definitions/sqlite.sql +5 -0
  52. data/test/fixtures/db_definitions/sqlserver.sql +5 -1
  53. data/test/fixtures/fixture_database.sqlite +0 -0
  54. data/test/validations_test.rb +21 -0
  55. metadata +22 -2
@@ -2,6 +2,7 @@ require 'abstract_unit'
2
2
  require 'fixtures/topic'
3
3
  require 'fixtures/reply'
4
4
  require 'fixtures/company'
5
+ require 'fixtures/project'
5
6
  require 'fixtures/default'
6
7
  require 'fixtures/auto_id'
7
8
  require 'fixtures/column_name'
@@ -26,7 +27,7 @@ end
26
27
  class Booleantest < ActiveRecord::Base; end
27
28
 
28
29
  class BasicsTest < Test::Unit::TestCase
29
- fixtures :topics, :companies
30
+ fixtures :topics, :companies, :projects
30
31
 
31
32
  def test_set_attributes
32
33
  topic = Topic.find(1)
@@ -100,6 +101,10 @@ class BasicsTest < Test::Unit::TestCase
100
101
  topic.content << "five"
101
102
  assert_equal(%w( one two three four five ), topic.content)
102
103
  end
104
+
105
+ def test_attributes_hash
106
+ assert_equal @projects["action_controller"].to_hash, @action_controller.attributes
107
+ end
103
108
 
104
109
  def test_create
105
110
  topic = Topic.new
@@ -367,6 +372,9 @@ class BasicsTest < Test::Unit::TestCase
367
372
  assert !Topic.find(1).approved?
368
373
  Topic.find(1).update_attribute("approved", true)
369
374
  assert Topic.find(1).approved?
375
+
376
+ Topic.find(1).update_attribute(:approved, false)
377
+ assert !Topic.find(1).approved?
370
378
  end
371
379
 
372
380
  def test_mass_assignment_protection
@@ -585,4 +593,45 @@ class BasicsTest < Test::Unit::TestCase
585
593
  assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1) }
586
594
  assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
587
595
  end
596
+
597
+ def test_increment_attribute
598
+ assert_equal 0, @topics["first"].find.replies_count
599
+ @topics["first"].find.increment! :replies_count
600
+ assert_equal 1, @topics["first"].find.replies_count
601
+
602
+ @topics["first"].find.increment(:replies_count).increment!(:replies_count)
603
+ assert_equal 3, @topics["first"].find.replies_count
604
+ end
605
+
606
+ def test_increment_nil_attribute
607
+ assert_nil @topics["first"].find.parent_id
608
+ @topics["first"].find.increment! :parent_id
609
+ assert_equal 1, @topics["first"].find.parent_id
610
+ end
611
+
612
+ def test_decrement_attribute
613
+ @topics["first"].find.increment(:replies_count).increment!(:replies_count)
614
+ assert_equal 2, @topics["first"].find.replies_count
615
+
616
+ @topics["first"].find.decrement!(:replies_count)
617
+ assert_equal 1, @topics["first"].find.replies_count
618
+
619
+ @topics["first"].find.decrement(:replies_count).decrement!(:replies_count)
620
+ assert_equal -1, @topics["first"].find.replies_count
621
+ end
622
+
623
+ def test_toggle_attribute
624
+ assert !@topics["first"].find.approved?
625
+ @topics["first"].find.toggle!(:approved)
626
+ assert @topics["first"].find.approved?
627
+ end
628
+
629
+ def test_reload
630
+ t1 = Topic.find(1)
631
+ t2 = Topic.find(1)
632
+ t1.title = "something else"
633
+ t1.save
634
+ t2.reload
635
+ assert_equal t1.title, t2.title
636
+ end
588
637
  end
@@ -227,4 +227,20 @@ class CallbacksTest < Test::Unit::TestCase
227
227
  [ :after_initialize, :method ]
228
228
  ], david.history
229
229
  end
230
+
231
+ def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
232
+ david = CallbackDeveloper.find(1)
233
+ CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false }
234
+ CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] }
235
+ david.save
236
+ assert_equal [
237
+ [ :after_find, :method ],
238
+ [ :after_initialize, :method ],
239
+ [ :before_validation, :string ],
240
+ [ :before_validation, :proc ],
241
+ [ :before_validation, :object ],
242
+ [ :before_validation, :block ],
243
+ [ :before_validation, :returning_false ]
244
+ ], david.history
245
+ end
230
246
  end
@@ -10,7 +10,7 @@ db2 = 'activerecord_unittest2'
10
10
  ActiveRecord::Base.establish_connection(
11
11
  :adapter => "mysql",
12
12
  :host => "localhost",
13
- :username => "root",
13
+ :username => "rails",
14
14
  :password => "",
15
15
  :database => db1
16
16
  )
@@ -18,7 +18,7 @@ ActiveRecord::Base.establish_connection(
18
18
  Course.establish_connection(
19
19
  :adapter => "mysql",
20
20
  :host => "localhost",
21
- :username => "root",
21
+ :username => "rails",
22
22
  :password => "",
23
23
  :database => db2
24
24
  )
@@ -0,0 +1,34 @@
1
+ print "Using native SQLite3\n"
2
+ require 'fixtures/course'
3
+ require 'logger'
4
+ ActiveRecord::Base.logger = Logger.new("debug.log")
5
+ ActiveRecord::Base.logger.level = Logger::DEBUG
6
+
7
+ BASE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../fixtures')
8
+ sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite3"
9
+ sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite3"
10
+
11
+ def make_connection(clazz, db_file, db_definitions_file)
12
+ unless File.exist?(db_file)
13
+ puts "SQLite3 database not found at #{db_file}. Rebuilding it."
14
+ sqlite_command = "sqlite3 #{db_file} 'create table a (a integer); drop table a;'"
15
+ puts "Executing '#{sqlite_command}'"
16
+ `#{sqlite_command}`
17
+ clazz.establish_connection(
18
+ :adapter => "sqlite3",
19
+ :dbfile => db_file)
20
+ script = File.read("#{BASE_DIR}/db_definitions/#{db_definitions_file}")
21
+ # SQLite-Ruby has problems with semi-colon separated commands, so split and execute one at a time
22
+ script.split(';').each do
23
+ |command|
24
+ clazz.connection.execute(command) unless command.strip.empty?
25
+ end
26
+ else
27
+ clazz.establish_connection(
28
+ :adapter => "sqlite3",
29
+ :dbfile => db_file)
30
+ end
31
+ end
32
+
33
+ make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql')
34
+ make_connection(Course, sqlite_test_db2, 'sqlite2.sql')
@@ -138,14 +138,14 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
138
138
  end
139
139
 
140
140
  def test_force_reload
141
- firm = Firm.new
141
+ firm = Firm.new("name" => "A New Firm, Inc")
142
142
  firm.save
143
143
  firm.clients.each {|c|} # forcing to load all clients
144
144
  assert firm.clients.empty?, "New firm shouldn't have client objects"
145
145
  assert !firm.has_clients?, "New firm shouldn't have clients"
146
146
  assert_equal 0, firm.clients_count, "New firm should have 0 clients"
147
147
 
148
- client = Client.new("firm_id" => firm.id)
148
+ client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
149
149
  client.save
150
150
 
151
151
  assert firm.clients.empty?, "New firm should have cached no client objects"
@@ -340,4 +340,38 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
340
340
  assert_equal 2, Firm.find_first.find_all_in_clients("type = 'Client'").length
341
341
  assert_equal 1, Firm.find_first.find_all_in_clients("name = 'Summit'").length
342
342
  end
343
+
344
+ def test_has_one
345
+ assert @signals37.account?(Account.find(1))
346
+ assert @signals37.has_account?, "37signals should have an account"
347
+ assert Account.find(1).firm?(@signals37), "37signals account should be able to backtrack"
348
+ assert Account.find(1).has_firm?, "37signals account should be able to backtrack"
349
+
350
+ assert !Account.find(2).has_firm?, "Unknown isn't linked"
351
+ assert !Account.find(2).firm?(@signals37), "Unknown isn't linked"
352
+ end
353
+
354
+ def test_has_one_build
355
+ firm = Firm.new("name" => "GlobalMegaCorp")
356
+ assert firm.save
357
+
358
+ account = firm.build_account("credit_limit" => 1000)
359
+ assert account.save
360
+ assert_equal account, firm.account
361
+ end
362
+
363
+ def test_has_one_failing_build_association
364
+ firm = Firm.new("name" => "GlobalMegaCorp")
365
+ firm.save
366
+
367
+ account = firm.build_account
368
+ assert !account.save
369
+ assert_equal "can't be empty", account.errors.on("credit_limit")
370
+ end
371
+
372
+ def test_has_one_create
373
+ firm = Firm.new("name" => "GlobalMegaCorp")
374
+ firm.save
375
+ assert_equal firm.create_account("credit_limit" => 1000), firm.account
376
+ end
343
377
  end
@@ -1,5 +1,7 @@
1
1
  class Company < ActiveRecord::Base
2
2
  attr_protected :rating
3
+
4
+ validates_presence_of :name
3
5
  end
4
6
 
5
7
 
@@ -0,0 +1,3 @@
1
+ class Computer < ActiveRecord::Base
2
+ belongs_to :developer, :foreign_key=>'developer'
3
+ end
@@ -0,0 +1,3 @@
1
+ workstation:
2
+ id: 1
3
+ developer: 1
@@ -122,3 +122,8 @@ CREATE TABLE binaries (
122
122
  data blob(50000),
123
123
  PRIMARY KEY (id)
124
124
  );
125
+
126
+ CREATE TABLE computers (
127
+ id int generated by default as identity (start with +10000),
128
+ developer int NOT NULL
129
+ );
@@ -121,4 +121,9 @@ CREATE TABLE `binaries` (
121
121
  `id` int(11) NOT NULL auto_increment,
122
122
  `data` mediumblob,
123
123
  PRIMARY KEY (`id`)
124
+ );
125
+
126
+ CREATE TABLE `computers` (
127
+ `id` INTEGER NOT NULL PRIMARY KEY,
128
+ `developer` INTEGER NOT NULL
124
129
  );
@@ -139,4 +139,9 @@ CREATE TABLE binaries (
139
139
  id serial ,
140
140
  data bytea,
141
141
  PRIMARY KEY (id)
142
+ );
143
+
144
+ CREATE TABLE computers (
145
+ id serial,
146
+ developer integer NOT NULL
142
147
  );
@@ -108,4 +108,9 @@ CREATE TABLE 'people' (
108
108
  CREATE TABLE 'binaries' (
109
109
  'id' INTEGER NOT NULL PRIMARY KEY,
110
110
  'data' BLOB DEFAULT NULL
111
+ );
112
+
113
+ CREATE TABLE 'computers' (
114
+ 'id' INTEGER NOT NULL PRIMARY KEY,
115
+ 'developer' INTEGER NOT NULL
111
116
  );
@@ -122,4 +122,8 @@ CREATE TABLE binaries (
122
122
  PRIMARY KEY (id)
123
123
  );
124
124
 
125
-
125
+ CREATE TABLE computers (
126
+ id int NOT NULL IDENTITY(1, 1),
127
+ developer int NOT NULL,
128
+ PRIMARY KEY (id)
129
+ );
@@ -389,6 +389,27 @@ class ValidationsTest < Test::Unit::TestCase
389
389
  assert_equal "hoo 5", t.errors["title"]
390
390
  end
391
391
 
392
+ def test_validates_associated_many
393
+ Topic.validates_associated( :replies )
394
+ t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
395
+ t.replies << [r = Reply.create("title" => "A reply"), Reply.create("title" => "Another reply", "content" => "with content!")]
396
+ assert !t.valid?
397
+ assert t.errors.on(:replies)
398
+ r.content = "non-empty"
399
+ assert t.valid?
400
+ end
401
+
402
+ def test_validates_associated_one
403
+ Reply.validates_associated( :topic )
404
+ Topic.validates_presence_of( :content )
405
+ r = Reply.create("title" => "A reply", "content" => "with content!")
406
+ r.topic = Topic.create("title" => "uhohuhoh")
407
+ assert !r.valid?
408
+ assert r.errors.on(:topic)
409
+ r.topic.content = "non-empty"
410
+ assert r.valid?
411
+ end
412
+
392
413
  def test_throw_away_typing
393
414
  d = Developer.create "name" => "David", "salary" => "100,000"
394
415
  assert !d.valid?
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.4
3
3
  specification_version: 1
4
4
  name: activerecord
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.4.0
7
- date: 2005-01-04
6
+ version: 1.5.0
7
+ date: 2005-01-17
8
8
  summary: Implements the ActiveRecord pattern for ORM.
9
9
  require_paths:
10
10
  - lib
@@ -58,8 +58,11 @@ files:
58
58
  - lib/active_record/acts/list.rb
59
59
  - lib/active_record/acts/tree.rb
60
60
  - lib/active_record/associations/association_collection.rb
61
+ - lib/active_record/associations/association_proxy.rb
62
+ - lib/active_record/associations/belongs_to_association.rb
61
63
  - lib/active_record/associations/has_and_belongs_to_many_association.rb
62
64
  - lib/active_record/associations/has_many_association.rb
65
+ - lib/active_record/associations/has_one_association.rb
63
66
  - lib/active_record/connection_adapters/abstract_adapter.rb
64
67
  - lib/active_record/connection_adapters/db2_adapter.rb
65
68
  - lib/active_record/connection_adapters/mysql_adapter.rb
@@ -71,12 +74,25 @@ files:
71
74
  - lib/active_record/support/class_attribute_accessors.rb
72
75
  - lib/active_record/support/class_inheritable_attributes.rb
73
76
  - lib/active_record/support/clean_logger.rb
77
+ - lib/active_record/support/core_ext
78
+ - lib/active_record/support/core_ext.rb
74
79
  - lib/active_record/support/dependencies.rb
75
80
  - lib/active_record/support/inflector.rb
76
81
  - lib/active_record/support/misc.rb
77
82
  - lib/active_record/support/module_attribute_accessors.rb
83
+ - lib/active_record/support/core_ext/hash
84
+ - lib/active_record/support/core_ext/hash.rb
85
+ - lib/active_record/support/core_ext/numeric
86
+ - lib/active_record/support/core_ext/numeric.rb
87
+ - lib/active_record/support/core_ext/string
88
+ - lib/active_record/support/core_ext/string.rb
89
+ - lib/active_record/support/core_ext/hash/keys.rb
90
+ - lib/active_record/support/core_ext/numeric/bytes.rb
91
+ - lib/active_record/support/core_ext/numeric/time.rb
92
+ - lib/active_record/support/core_ext/string/inflections.rb
78
93
  - lib/active_record/vendor/db2.rb
79
94
  - lib/active_record/vendor/mysql.rb
95
+ - lib/active_record/vendor/mysql411.rb
80
96
  - lib/active_record/vendor/simple.rb
81
97
  - lib/active_record/wrappers/yaml_wrapper.rb
82
98
  - test/abstract_unit.rb
@@ -108,11 +124,13 @@ files:
108
124
  - test/connections/native_mysql
109
125
  - test/connections/native_postgresql
110
126
  - test/connections/native_sqlite
127
+ - test/connections/native_sqlite3
111
128
  - test/connections/native_sqlserver
112
129
  - test/connections/native_db2/connection.rb
113
130
  - test/connections/native_mysql/connection.rb
114
131
  - test/connections/native_postgresql/connection.rb
115
132
  - test/connections/native_sqlite/connection.rb
133
+ - test/connections/native_sqlite3/connection.rb
116
134
  - test/connections/native_sqlserver/connection.rb
117
135
  - test/fixtures/accounts.yml
118
136
  - test/fixtures/associations.png
@@ -123,6 +141,8 @@ files:
123
141
  - test/fixtures/companies.yml
124
142
  - test/fixtures/company.rb
125
143
  - test/fixtures/company_in_module.rb
144
+ - test/fixtures/computer.rb
145
+ - test/fixtures/computers.yml
126
146
  - test/fixtures/course.rb
127
147
  - test/fixtures/courses.yml
128
148
  - test/fixtures/customer.rb