tenacity 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/EXTEND.rdoc +11 -1
- data/README.rdoc +4 -1
- data/Rakefile +20 -9
- data/history.txt +21 -0
- data/lib/tenacity.rb +12 -4
- data/lib/tenacity/associates_proxy.rb +67 -0
- data/lib/tenacity/association.rb +19 -6
- data/lib/tenacity/associations/has_many.rb +6 -0
- data/lib/tenacity/class_methods.rb +52 -1
- data/lib/tenacity/instance_methods.rb +7 -3
- data/lib/tenacity/orm_ext/activerecord.rb +30 -13
- data/lib/tenacity/orm_ext/couchrest.rb +140 -0
- data/lib/tenacity/orm_ext/datamapper.rb +139 -0
- data/lib/tenacity/orm_ext/mongo_mapper.rb +88 -80
- data/lib/tenacity/orm_ext/mongoid.rb +108 -0
- data/lib/tenacity/orm_ext/sequel.rb +134 -0
- data/lib/tenacity/version.rb +1 -1
- data/tenacity.gemspec +14 -3
- data/test/association_features/belongs_to_test.rb +42 -0
- data/test/association_features/has_many_test.rb +110 -0
- data/test/association_features/has_one_test.rb +41 -0
- data/test/associations/belongs_to_test.rb +36 -127
- data/test/associations/has_many_test.rb +77 -196
- data/test/associations/has_one_test.rb +22 -84
- data/test/core/classmethods_test.rb +24 -22
- data/test/fixtures/active_record_has_many_target.rb +10 -0
- data/test/fixtures/active_record_has_one_target.rb +10 -0
- data/test/fixtures/{active_record_nuts.rb → active_record_nut.rb} +0 -0
- data/test/fixtures/active_record_object.rb +17 -0
- data/test/fixtures/couch_rest_door.rb +0 -2
- data/test/fixtures/couch_rest_has_many_target.rb +12 -0
- data/test/fixtures/couch_rest_has_one_target.rb +12 -0
- data/test/fixtures/couch_rest_object.rb +19 -0
- data/test/fixtures/couch_rest_windshield.rb +0 -2
- data/test/fixtures/data_mapper_has_many_target.rb +19 -0
- data/test/fixtures/data_mapper_has_one_target.rb +19 -0
- data/test/fixtures/data_mapper_object.rb +20 -0
- data/test/fixtures/mongo_mapper_ash_tray.rb +0 -2
- data/test/fixtures/mongo_mapper_dashboard.rb +0 -2
- data/test/fixtures/mongo_mapper_has_many_target.rb +11 -0
- data/test/fixtures/mongo_mapper_has_one_target.rb +11 -0
- data/test/fixtures/mongo_mapper_object.rb +18 -0
- data/test/fixtures/mongo_mapper_vent.rb +0 -2
- data/test/fixtures/mongo_mapper_wheel.rb +0 -2
- data/test/fixtures/mongoid_has_many_target.rb +13 -0
- data/test/fixtures/mongoid_has_one_target.rb +13 -0
- data/test/fixtures/mongoid_object.rb +20 -0
- data/test/fixtures/sequel_has_many_target.rb +10 -0
- data/test/fixtures/sequel_has_one_target.rb +10 -0
- data/test/fixtures/sequel_object.rb +17 -0
- data/test/helpers/active_record_test_helper.rb +51 -0
- data/test/helpers/data_mapper_test_helper.rb +44 -0
- data/test/helpers/mongoid_test_helper.rb +21 -0
- data/test/helpers/sequel_test_helper.rb +60 -0
- data/test/orm_ext/activerecord_test.rb +55 -35
- data/test/orm_ext/couchrest_test.rb +66 -46
- data/test/orm_ext/datamapper_test.rb +112 -0
- data/test/orm_ext/mongo_mapper_test.rb +64 -44
- data/test/orm_ext/mongoid_test.rb +121 -0
- data/test/orm_ext/sequel_test.rb +113 -0
- data/test/test_helper.rb +87 -11
- metadata +159 -59
- data/lib/tenacity/orm_ext/couchrest/couchrest_extended_document.rb +0 -42
- data/lib/tenacity/orm_ext/couchrest/couchrest_model.rb +0 -44
- data/lib/tenacity/orm_ext/couchrest/tenacity_class_methods.rb +0 -43
- data/lib/tenacity/orm_ext/couchrest/tenacity_instance_methods.rb +0 -21
- data/test/fixtures/couch_rest_radio.rb +0 -10
- data/test/fixtures/mongo_mapper_button.rb +0 -6
@@ -0,0 +1,108 @@
|
|
1
|
+
module Tenacity
|
2
|
+
# Tenacity relationships on Mongoid objects require no special keys
|
3
|
+
# defined on the object. Tenacity will define the keys that it needs
|
4
|
+
# to support the relationships. Take the following class for example:
|
5
|
+
#
|
6
|
+
# class Car
|
7
|
+
# include Mongoid::Document
|
8
|
+
# include Tenacity
|
9
|
+
#
|
10
|
+
# t_has_many :wheels
|
11
|
+
# t_has_one :dashboard
|
12
|
+
# t_belongs_to :driver
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# == t_belongs_to
|
16
|
+
#
|
17
|
+
# The +t_belongs_to+ association will define a key named after the association.
|
18
|
+
# The example above will create a key named <tt>:driver_id</tt>
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# == t_has_one
|
22
|
+
#
|
23
|
+
# The +t_has_one+ association will not define any new keys on the object, since
|
24
|
+
# the associated object holds the foreign key.
|
25
|
+
#
|
26
|
+
#
|
27
|
+
# == t_has_many
|
28
|
+
#
|
29
|
+
# The +t_has_many+ association will define a key named after the association.
|
30
|
+
# The example above will create a key named <tt>:wheels_ids</tt>
|
31
|
+
#
|
32
|
+
module Mongoid
|
33
|
+
|
34
|
+
def self.setup(model) #:nodoc:
|
35
|
+
require 'mongoid'
|
36
|
+
if model.included_modules.include?(::Mongoid::Document)
|
37
|
+
model.send :include, Mongoid::InstanceMethods
|
38
|
+
model.extend Mongoid::ClassMethods
|
39
|
+
end
|
40
|
+
rescue LoadError
|
41
|
+
# Mongoid not available
|
42
|
+
end
|
43
|
+
|
44
|
+
module ClassMethods #:nodoc:
|
45
|
+
def _t_find(id)
|
46
|
+
(id.nil? || id.to_s.strip == "") ? nil : find(id)
|
47
|
+
rescue ::Mongoid::Errors::DocumentNotFound
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def _t_find_bulk(ids)
|
52
|
+
find(ids)
|
53
|
+
rescue ::Mongoid::Errors::DocumentNotFound
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
|
57
|
+
def _t_find_first_by_associate(property, id)
|
58
|
+
find(:first, :conditions => { property => id })
|
59
|
+
end
|
60
|
+
|
61
|
+
def _t_find_all_by_associate(property, id)
|
62
|
+
find(:all, :conditions => { property => id })
|
63
|
+
end
|
64
|
+
|
65
|
+
def _t_initialize_has_many_association(association)
|
66
|
+
unless self.respond_to?(association.foreign_keys_property)
|
67
|
+
field association.foreign_keys_property, :type => Array
|
68
|
+
after_save { |record| self.class._t_save_associates(record, association) }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def _t_initialize_belongs_to_association(association)
|
73
|
+
unless self.respond_to?(association.foreign_key)
|
74
|
+
field association.foreign_key, :type => String
|
75
|
+
before_save { |record| self.class._t_stringify_belongs_to_value(record, association) }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def _t_delete(ids, run_callbacks=true)
|
80
|
+
docs = _t_find_bulk(ids)
|
81
|
+
if run_callbacks
|
82
|
+
docs.each { |doc| doc.destroy }
|
83
|
+
else
|
84
|
+
docs.each { |doc| doc.delete }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
module InstanceMethods #:nodoc:
|
90
|
+
def _t_reload
|
91
|
+
reload
|
92
|
+
end
|
93
|
+
|
94
|
+
def _t_associate_many(association, associate_ids)
|
95
|
+
self.send(association.foreign_keys_property + '=', associate_ids.map { |associate_id| associate_id.to_s })
|
96
|
+
end
|
97
|
+
|
98
|
+
def _t_get_associate_ids(association)
|
99
|
+
self.send(association.foreign_keys_property)
|
100
|
+
end
|
101
|
+
|
102
|
+
def _t_clear_associates(association)
|
103
|
+
self.send(association.foreign_keys_property + '=', [])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Tenacity
|
2
|
+
# Tenacity relationships on Sequel objects require that certain columns
|
3
|
+
# exist on the associated table, and that join tables exist for one-to-many
|
4
|
+
# relationships. Take the following class for example:
|
5
|
+
#
|
6
|
+
# class Car < Sequel::Model
|
7
|
+
# include Tenacity
|
8
|
+
#
|
9
|
+
# t_has_many :wheels
|
10
|
+
# t_has_one :dashboard
|
11
|
+
# t_belongs_to :driver
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# == t_belongs_to
|
16
|
+
#
|
17
|
+
# The +t_belongs_to+ association requires that a property exist in the table
|
18
|
+
# to hold the id of the assoicated object.
|
19
|
+
#
|
20
|
+
# DB.create_table :cars do
|
21
|
+
# primary_key :id
|
22
|
+
# String :driver_id
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
#
|
26
|
+
# == t_has_one
|
27
|
+
#
|
28
|
+
# The +t_has_one+ association requires no special column in the table, since
|
29
|
+
# the associated object holds the foreign key.
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# == t_has_many
|
33
|
+
#
|
34
|
+
# The +t_has_many+ association requires that a join table exist to store the
|
35
|
+
# associations. The name of the join table follows ActiveRecord conventions.
|
36
|
+
# The name of the join table in this example would be cars_wheels, since cars
|
37
|
+
# comes before wheels when shorted alphabetically.
|
38
|
+
#
|
39
|
+
# DB.create_table :cars_wheels do
|
40
|
+
# Integer :car_id
|
41
|
+
# String :wheel_id
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
module Sequel
|
45
|
+
|
46
|
+
def self.setup(model)
|
47
|
+
require 'sequel'
|
48
|
+
if model.ancestors.include?(::Sequel::Model)
|
49
|
+
model.send :include, Sequel::InstanceMethods
|
50
|
+
model.extend Sequel::ClassMethods
|
51
|
+
end
|
52
|
+
rescue LoadError
|
53
|
+
# Sequel not available
|
54
|
+
end
|
55
|
+
|
56
|
+
module ClassMethods #:nodoc:
|
57
|
+
attr_accessor :_t_has_many_associations
|
58
|
+
attr_accessor :_t_belongs_to_associations
|
59
|
+
|
60
|
+
def _t_find(id)
|
61
|
+
self[id]
|
62
|
+
end
|
63
|
+
|
64
|
+
def _t_find_bulk(ids)
|
65
|
+
return [] if ids.nil? || ids.empty?
|
66
|
+
filter(:id => ids)
|
67
|
+
end
|
68
|
+
|
69
|
+
def _t_find_first_by_associate(property, id)
|
70
|
+
first(property.to_sym => id)
|
71
|
+
end
|
72
|
+
|
73
|
+
def _t_find_all_by_associate(property, id)
|
74
|
+
filter(property => id)
|
75
|
+
end
|
76
|
+
|
77
|
+
def _t_initialize_has_many_association(association)
|
78
|
+
@_t_has_many_associations ||= []
|
79
|
+
@_t_has_many_associations << association
|
80
|
+
end
|
81
|
+
|
82
|
+
def _t_initialize_belongs_to_association(association)
|
83
|
+
@_t_belongs_to_associations ||= []
|
84
|
+
@_t_belongs_to_associations << association
|
85
|
+
end
|
86
|
+
|
87
|
+
def _t_delete(ids, run_callbacks=true)
|
88
|
+
if run_callbacks
|
89
|
+
filter(:id => ids).destroy
|
90
|
+
else
|
91
|
+
filter(:id => ids).delete
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
module InstanceMethods #:nodoc:
|
97
|
+
def before_save
|
98
|
+
associations = self.class._t_belongs_to_associations || []
|
99
|
+
associations.each { |association| self.class._t_stringify_belongs_to_value(self, association) }
|
100
|
+
super
|
101
|
+
end
|
102
|
+
|
103
|
+
def after_save
|
104
|
+
associations = self.class._t_has_many_associations || []
|
105
|
+
associations.each { |association| self.class._t_save_associates(self, association) }
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
def _t_reload
|
110
|
+
reload
|
111
|
+
end
|
112
|
+
|
113
|
+
def _t_clear_associates(association)
|
114
|
+
db["delete from #{association.join_table} where #{association.association_key} = #{self.id}"].delete
|
115
|
+
end
|
116
|
+
|
117
|
+
def _t_associate_many(association, associate_ids)
|
118
|
+
db.transaction do
|
119
|
+
_t_clear_associates(association)
|
120
|
+
associate_ids.each do |associate_id|
|
121
|
+
db["insert into #{association.join_table} (#{association.association_key}, #{association.association_foreign_key}) values (#{self.id}, '#{associate_id}')"].insert
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def _t_get_associate_ids(association)
|
127
|
+
return [] if self.id.nil?
|
128
|
+
rows = db["select #{association.association_foreign_key} from #{association.join_table} where #{association.association_key} = #{self.id}"].all
|
129
|
+
rows.map { |row| row[association.association_foreign_key.to_sym] }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
data/lib/tenacity/version.rb
CHANGED
data/tenacity.gemspec
CHANGED
@@ -22,12 +22,23 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_development_dependency "rake", "~> 0.8.7"
|
23
23
|
s.add_development_dependency "rcov", "~> 0.9.9"
|
24
24
|
s.add_development_dependency "shoulda", "~> 2.11.3"
|
25
|
+
s.add_development_dependency "yard", "~> 0.6.4"
|
26
|
+
|
27
|
+
# Relational DBs
|
28
|
+
s.add_development_dependency "sqlite3-ruby", "~> 1.3.1"
|
29
|
+
s.add_development_dependency "activerecord", "~> 3.0.0"
|
30
|
+
s.add_development_dependency "datamapper", "~> 1.0.2"
|
31
|
+
s.add_development_dependency "dm-sqlite-adapter", "~> 1.0.2"
|
32
|
+
s.add_development_dependency "sequel", "~> 3.19.0"
|
33
|
+
|
34
|
+
# MongoDB
|
25
35
|
s.add_development_dependency "mongo_mapper", "~> 0.8.6"
|
26
36
|
s.add_development_dependency "bson_ext", "~> 1.1.3"
|
27
|
-
s.add_development_dependency "
|
28
|
-
|
37
|
+
s.add_development_dependency "mongoid", "~> 2.0.0.beta"
|
38
|
+
|
39
|
+
# CouchDB
|
29
40
|
s.add_development_dependency "couchrest", "~> 1.0.0"
|
30
|
-
s.add_development_dependency "couchrest_model"
|
41
|
+
s.add_development_dependency "couchrest_model", "~> 1.0.0.beta"
|
31
42
|
|
32
43
|
s.files = `git ls-files`.split("\n")
|
33
44
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BelongsToTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "A class with a belongs_to association to another class" do
|
6
|
+
setup do
|
7
|
+
setup_fixtures
|
8
|
+
@car = ActiveRecordCar.create
|
9
|
+
@wheel = MongoMapperWheel.create(:active_record_car => @car)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "memoize the association" do
|
13
|
+
assert_equal @car, @wheel.active_record_car
|
14
|
+
|
15
|
+
other_car = ActiveRecordCar.create
|
16
|
+
assert_equal @car, MongoMapperWheel.find(@wheel.id).active_record_car
|
17
|
+
MongoMapperWheel.update(@wheel.id, :active_record_car => other_car)
|
18
|
+
assert_equal other_car, MongoMapperWheel.find(@wheel.id).active_record_car
|
19
|
+
|
20
|
+
assert_equal @car, @wheel.active_record_car
|
21
|
+
assert_equal other_car, @wheel.active_record_car(true)
|
22
|
+
end
|
23
|
+
|
24
|
+
should "be able to specify the class name of the associated class" do
|
25
|
+
dashboard = MongoMapperDashboard.create
|
26
|
+
ash_tray = MongoMapperAshTray.create(:dashboard => dashboard)
|
27
|
+
assert_equal dashboard, ash_tray.dashboard
|
28
|
+
end
|
29
|
+
|
30
|
+
should "be able to specify the foreign key to use for the associated class" do
|
31
|
+
car = ActiveRecordCar.create
|
32
|
+
windshield = CouchRestWindshield.create(:active_record_car => car)
|
33
|
+
assert_equal car.id.to_s, windshield.car_id
|
34
|
+
assert !windshield.respond_to?(:active_record_car_id)
|
35
|
+
|
36
|
+
engine = ActiveRecordEngine.create(:active_record_car => car)
|
37
|
+
assert_equal car.id, engine.car_id
|
38
|
+
assert !engine.respond_to?(:active_record_car_id)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HasManyTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "A class with a belongs_to association to another class" do
|
6
|
+
setup do
|
7
|
+
setup_fixtures
|
8
|
+
@car = ActiveRecordCar.create
|
9
|
+
@wheels = [MongoMapperWheel.create, MongoMapperWheel.create, MongoMapperWheel.create]
|
10
|
+
|
11
|
+
@car.mongo_mapper_wheels = @wheels
|
12
|
+
@car.save
|
13
|
+
end
|
14
|
+
|
15
|
+
should "memoize the association" do
|
16
|
+
assert_equal @wheels, @car.mongo_mapper_wheels
|
17
|
+
|
18
|
+
other_wheels = [MongoMapperWheel.create, MongoMapperWheel.create, MongoMapperWheel.create]
|
19
|
+
assert_equal @wheels, ActiveRecordCar.find(@car.id).mongo_mapper_wheels
|
20
|
+
ActiveRecordCar.find(@car.id).update_attribute(:mongo_mapper_wheels, other_wheels)
|
21
|
+
assert_equal other_wheels, ActiveRecordCar.find(@car.id).mongo_mapper_wheels
|
22
|
+
|
23
|
+
assert_equal @wheels, @car.mongo_mapper_wheels
|
24
|
+
assert_equal other_wheels, @car.mongo_mapper_wheels(true)
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be able to specify the class name of the associated class" do
|
28
|
+
vent_1 = MongoMapperVent.create
|
29
|
+
vent_2 = MongoMapperVent.create
|
30
|
+
vent_3 = MongoMapperVent.create
|
31
|
+
dashboard = MongoMapperDashboard.create
|
32
|
+
dashboard.vents = [vent_1, vent_2, vent_3]
|
33
|
+
dashboard.save
|
34
|
+
assert_set_equal [vent_1, vent_2, vent_3], MongoMapperDashboard.find(dashboard.id).vents
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to specify the foreign key to use for the class" do
|
38
|
+
car = ActiveRecordCar.create
|
39
|
+
door_1 = CouchRestDoor.create({})
|
40
|
+
door_2 = CouchRestDoor.create({})
|
41
|
+
door_3 = CouchRestDoor.create({})
|
42
|
+
car.couch_rest_doors = [door_1, door_2, door_3]
|
43
|
+
car.save
|
44
|
+
|
45
|
+
assert_set_equal [door_1, door_2, door_3], ActiveRecordCar.find(car.id).couch_rest_doors
|
46
|
+
assert_set_equal [door_1.id.to_s, door_2.id.to_s, door_3.id.to_s], ActiveRecordCar.find(car.id).couch_rest_door_ids
|
47
|
+
end
|
48
|
+
|
49
|
+
should "save the associate object when it is added as an associate if the parent object is saved" do
|
50
|
+
car = ActiveRecordCar.create
|
51
|
+
door_1 = CouchRestDoor.new({})
|
52
|
+
assert_nil door_1.id
|
53
|
+
|
54
|
+
old_count = CouchRestDoor.count
|
55
|
+
car.couch_rest_doors << door_1
|
56
|
+
assert_equal old_count + 1, CouchRestDoor.count
|
57
|
+
end
|
58
|
+
|
59
|
+
should "not save the associate object when it is added as an associate if the parent object is not saved" do
|
60
|
+
car = ActiveRecordCar.new
|
61
|
+
door_1 = CouchRestDoor.new({})
|
62
|
+
assert_nil door_1.id
|
63
|
+
|
64
|
+
old_count = CouchRestDoor.count
|
65
|
+
car.couch_rest_doors << door_1
|
66
|
+
assert_equal old_count, CouchRestDoor.count
|
67
|
+
end
|
68
|
+
|
69
|
+
should "save all unsaved associates when the parent object is saved" do
|
70
|
+
car = ActiveRecordCar.new
|
71
|
+
door_1 = CouchRestDoor.new({})
|
72
|
+
assert_nil door_1.id
|
73
|
+
|
74
|
+
old_count = CouchRestDoor.count
|
75
|
+
car.couch_rest_doors << door_1
|
76
|
+
assert_equal old_count, CouchRestDoor.count
|
77
|
+
car.save
|
78
|
+
assert_equal old_count + 1, CouchRestDoor.count
|
79
|
+
assert_set_equal [door_1], ActiveRecordCar.find(car.id).couch_rest_doors
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with a set of associates that need to be deleted" do
|
83
|
+
setup do
|
84
|
+
@new_car = ActiveRecordCar.create
|
85
|
+
@door_1 = CouchRestDoor.create({})
|
86
|
+
@door_2 = CouchRestDoor.create({})
|
87
|
+
@door_3 = CouchRestDoor.create({})
|
88
|
+
@new_car.couch_rest_doors = [@door_1, @door_2, @door_3]
|
89
|
+
@new_car.save
|
90
|
+
end
|
91
|
+
|
92
|
+
should "be able to delete all associates" do
|
93
|
+
assert_set_equal [@door_1, @door_2, @door_3], ActiveRecordCar.find(@new_car.id).couch_rest_doors
|
94
|
+
old_count = CouchRestDoor.count
|
95
|
+
@new_car.couch_rest_doors.delete_all
|
96
|
+
assert_equal old_count - 3, CouchRestDoor.count
|
97
|
+
assert_set_equal [], ActiveRecordCar.find(@new_car.id).couch_rest_doors
|
98
|
+
end
|
99
|
+
|
100
|
+
should "be able to destroy all associates" do
|
101
|
+
assert_set_equal [@door_1, @door_2, @door_3], ActiveRecordCar.find(@new_car.id).couch_rest_doors
|
102
|
+
old_count = CouchRestDoor.count
|
103
|
+
@new_car.couch_rest_doors.destroy_all
|
104
|
+
assert_equal old_count - 3, CouchRestDoor.count
|
105
|
+
assert_set_equal [], ActiveRecordCar.find(@new_car.id).couch_rest_doors
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HasOneTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "A class with a has_one association to another class" do
|
6
|
+
setup do
|
7
|
+
setup_fixtures
|
8
|
+
@climate_control_unit = ActiveRecordClimateControlUnit.create
|
9
|
+
@dashboard = MongoMapperDashboard.create(:active_record_climate_control_unit => @climate_control_unit)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "memoize the association" do
|
13
|
+
assert_equal @climate_control_unit, @dashboard.active_record_climate_control_unit
|
14
|
+
|
15
|
+
other_climate_control_unit = ActiveRecordClimateControlUnit.create
|
16
|
+
assert_equal @climate_control_unit, MongoMapperDashboard.find(@dashboard.id).active_record_climate_control_unit
|
17
|
+
ActiveRecordClimateControlUnit.update(@climate_control_unit.id, :mongo_mapper_dashboard_id => nil)
|
18
|
+
ActiveRecordClimateControlUnit.update(other_climate_control_unit.id, :mongo_mapper_dashboard_id => @dashboard.id)
|
19
|
+
assert_equal other_climate_control_unit, MongoMapperDashboard.find(@dashboard.id).active_record_climate_control_unit
|
20
|
+
|
21
|
+
assert_equal @climate_control_unit, @dashboard.active_record_climate_control_unit
|
22
|
+
assert_equal other_climate_control_unit, @dashboard.active_record_climate_control_unit(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be able to specify the class name of the associated class" do
|
26
|
+
ash_tray = MongoMapperAshTray.create
|
27
|
+
dashboard = MongoMapperDashboard.create(:ash_tray => ash_tray)
|
28
|
+
assert_equal ash_tray, dashboard.ash_tray
|
29
|
+
end
|
30
|
+
|
31
|
+
should "be able to specify the foreign key to use for the class" do
|
32
|
+
car = ActiveRecordCar.create
|
33
|
+
windshield = CouchRestWindshield.create(:active_record_car => car)
|
34
|
+
assert_equal windshield, car.couch_rest_windshield
|
35
|
+
|
36
|
+
engine = ActiveRecordEngine.create(:active_record_car => car)
|
37
|
+
assert_equal engine, car.active_record_engine
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|