datamapper 0.2.5 → 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.
Files changed (121) hide show
  1. data/CHANGELOG +5 -1
  2. data/FAQ +96 -0
  3. data/QUICKLINKS +12 -0
  4. data/README +57 -155
  5. data/environment.rb +61 -43
  6. data/example.rb +30 -12
  7. data/lib/data_mapper.rb +6 -1
  8. data/lib/data_mapper/adapters/abstract_adapter.rb +0 -57
  9. data/lib/data_mapper/adapters/data_object_adapter.rb +203 -97
  10. data/lib/data_mapper/adapters/mysql_adapter.rb +4 -0
  11. data/lib/data_mapper/adapters/postgresql_adapter.rb +7 -1
  12. data/lib/data_mapper/adapters/sql/coersion.rb +3 -2
  13. data/lib/data_mapper/adapters/sql/commands/load_command.rb +29 -10
  14. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +4 -0
  15. data/lib/data_mapper/adapters/sql/mappings/column.rb +13 -9
  16. data/lib/data_mapper/adapters/sql/mappings/conditions.rb +172 -0
  17. data/lib/data_mapper/adapters/sql/mappings/table.rb +43 -17
  18. data/lib/data_mapper/adapters/sqlite3_adapter.rb +9 -2
  19. data/lib/data_mapper/associations.rb +75 -3
  20. data/lib/data_mapper/associations/belongs_to_association.rb +70 -36
  21. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +195 -86
  22. data/lib/data_mapper/associations/has_many_association.rb +168 -61
  23. data/lib/data_mapper/associations/has_n_association.rb +23 -3
  24. data/lib/data_mapper/attributes.rb +73 -0
  25. data/lib/data_mapper/auto_migrations.rb +2 -6
  26. data/lib/data_mapper/base.rb +5 -9
  27. data/lib/data_mapper/database.rb +4 -3
  28. data/lib/data_mapper/embedded_value.rb +66 -30
  29. data/lib/data_mapper/identity_map.rb +1 -3
  30. data/lib/data_mapper/is/tree.rb +121 -0
  31. data/lib/data_mapper/migration.rb +155 -0
  32. data/lib/data_mapper/persistence.rb +532 -218
  33. data/lib/data_mapper/property.rb +306 -0
  34. data/lib/data_mapper/query.rb +164 -0
  35. data/lib/data_mapper/support/blank.rb +2 -2
  36. data/lib/data_mapper/support/connection_pool.rb +5 -6
  37. data/lib/data_mapper/support/enumerable.rb +3 -3
  38. data/lib/data_mapper/support/errors.rb +10 -1
  39. data/lib/data_mapper/support/inflector.rb +174 -238
  40. data/lib/data_mapper/support/object.rb +54 -0
  41. data/lib/data_mapper/support/serialization.rb +19 -1
  42. data/lib/data_mapper/support/string.rb +7 -16
  43. data/lib/data_mapper/support/symbol.rb +3 -15
  44. data/lib/data_mapper/support/typed_set.rb +68 -0
  45. data/lib/data_mapper/types/base.rb +44 -0
  46. data/lib/data_mapper/types/string.rb +34 -0
  47. data/lib/data_mapper/validations/number_validator.rb +40 -0
  48. data/lib/data_mapper/validations/string_validator.rb +20 -0
  49. data/lib/data_mapper/validations/validator.rb +13 -0
  50. data/performance.rb +26 -1
  51. data/profile_data_mapper.rb +1 -1
  52. data/rakefile.rb +42 -2
  53. data/spec/acts_as_tree_spec.rb +11 -3
  54. data/spec/adapters/data_object_adapter_spec.rb +31 -0
  55. data/spec/associations/belongs_to_association_spec.rb +98 -0
  56. data/spec/associations/has_and_belongs_to_many_association_spec.rb +377 -0
  57. data/spec/associations/has_many_association_spec.rb +337 -0
  58. data/spec/attributes_spec.rb +23 -1
  59. data/spec/auto_migrations_spec.rb +86 -29
  60. data/spec/callbacks_spec.rb +107 -0
  61. data/spec/column_spec.rb +5 -2
  62. data/spec/count_command_spec.rb +33 -1
  63. data/spec/database_spec.rb +18 -0
  64. data/spec/dependency_spec.rb +4 -2
  65. data/spec/embedded_value_spec.rb +8 -8
  66. data/spec/fixtures/people.yaml +1 -1
  67. data/spec/fixtures/projects.yaml +10 -1
  68. data/spec/fixtures/tasks.yaml +6 -0
  69. data/spec/fixtures/tasks_tasks.yaml +2 -0
  70. data/spec/fixtures/tomatoes.yaml +1 -0
  71. data/spec/is_a_tree_spec.rb +149 -0
  72. data/spec/load_command_spec.rb +71 -9
  73. data/spec/magic_columns_spec.rb +17 -2
  74. data/spec/migration_spec.rb +267 -0
  75. data/spec/models/animal.rb +1 -1
  76. data/spec/models/candidate.rb +8 -0
  77. data/spec/models/career.rb +1 -1
  78. data/spec/models/chain.rb +8 -0
  79. data/spec/models/comment.rb +1 -1
  80. data/spec/models/exhibit.rb +1 -1
  81. data/spec/models/fence.rb +7 -0
  82. data/spec/models/fruit.rb +2 -2
  83. data/spec/models/job.rb +8 -0
  84. data/spec/models/person.rb +2 -3
  85. data/spec/models/post.rb +1 -1
  86. data/spec/models/project.rb +21 -1
  87. data/spec/models/section.rb +1 -1
  88. data/spec/models/serializer.rb +1 -1
  89. data/spec/models/task.rb +9 -0
  90. data/spec/models/tomato.rb +27 -0
  91. data/spec/models/user.rb +8 -2
  92. data/spec/models/zoo.rb +2 -7
  93. data/spec/paranoia_spec.rb +1 -1
  94. data/spec/{base_spec.rb → persistence_spec.rb} +207 -18
  95. data/spec/postgres_spec.rb +48 -6
  96. data/spec/property_spec.rb +90 -9
  97. data/spec/query_spec.rb +71 -5
  98. data/spec/save_command_spec.rb +11 -0
  99. data/spec/spec_helper.rb +14 -11
  100. data/spec/support/blank_spec.rb +8 -0
  101. data/spec/support/inflector_spec.rb +41 -0
  102. data/spec/support/object_spec.rb +9 -0
  103. data/spec/{serialization_spec.rb → support/serialization_spec.rb} +1 -1
  104. data/spec/support/silence_spec.rb +15 -0
  105. data/spec/{support_spec.rb → support/string_spec.rb} +3 -3
  106. data/spec/support/struct_spec.rb +12 -0
  107. data/spec/support/typed_set_spec.rb +66 -0
  108. data/spec/table_spec.rb +3 -3
  109. data/spec/types/string.rb +81 -0
  110. data/spec/validates_uniqueness_of_spec.rb +17 -0
  111. data/spec/validations/number_validator.rb +59 -0
  112. data/spec/validations/string_validator.rb +14 -0
  113. metadata +59 -17
  114. data/do_performance.rb +0 -153
  115. data/lib/data_mapper/support/active_record_impersonation.rb +0 -103
  116. data/lib/data_mapper/support/weak_hash.rb +0 -46
  117. data/spec/active_record_impersonation_spec.rb +0 -129
  118. data/spec/associations_spec.rb +0 -232
  119. data/spec/conditions_spec.rb +0 -49
  120. data/spec/has_many_association_spec.rb +0 -173
  121. data/spec/models/animals_exhibit.rb +0 -8
@@ -1,153 +0,0 @@
1
- require 'benchmark'
2
- require 'lib/data_mapper'
3
-
4
- DataMapper::Database.setup({
5
- :adapter => 'do_mysql',
6
- :database => 'data_mapper_1',
7
- :username => 'root'
8
- })
9
-
10
- class DMAnimal < DataMapper::Base
11
- set_table_name 'animals'
12
- property :name, :string
13
- property :notes, :string
14
- end
15
-
16
- class DMPerson < DataMapper::Base
17
- set_table_name 'people'
18
- property :name, :string
19
- property :age, :integer
20
- property :occupation, :string
21
- property :notes, :text
22
- property :street, :string
23
- property :city, :string
24
- property :state, :string, :size => 2
25
- property :zip_code, :string, :size => 10
26
- end
27
-
28
- class Exhibit < DataMapper::Base
29
- property :name, :string
30
- belongs_to :zoo
31
- end
32
-
33
- class Zoo < DataMapper::Base
34
- property :name, :string
35
- has_many :exhibits
36
- end
37
-
38
- N = (ENV['N'] || 1000).to_i
39
-
40
- # 4.times do
41
- # [DMAnimal, Zoo, Exhibit].each do |klass|
42
- # klass.all.each do |instance|
43
- # klass.create(instance.attributes.reject { |k,v| k == :id })
44
- # end
45
- # end
46
- # end
47
-
48
- Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
49
-
50
- x.report('DataMapper:id') do
51
- N.times { DMAnimal[1] }
52
- end
53
-
54
- x.report('DataMapper:id:in-session') do
55
- database do
56
- N.times { DMAnimal[1] }
57
- end
58
- end
59
-
60
- x.report('DataMapper:all') do
61
- N.times { DMAnimal.all }
62
- end
63
-
64
- x.report('DataMapper:all:in-session') do
65
- database do
66
- N.times { DMAnimal.all }
67
- end
68
- end
69
-
70
- x.report('DataMapper:conditions:short') do
71
- N.times { Zoo[:name => 'Galveston'] }
72
- end
73
-
74
- x.report('DataMapper:conditions:short:in-session') do
75
- database do
76
- N.times { Zoo[:name => 'Galveston'] }
77
- end
78
- end
79
-
80
- x.report('DataMapper:conditions:long') do
81
- N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']) }
82
- end
83
-
84
- x.report('DataMapper:conditions:long:in-session') do
85
- database do
86
- N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']) }
87
- end
88
- end
89
-
90
- people = [
91
- ['Sam', 29, 'Programmer', 'A slow text field'],
92
- ['Amy', 28, 'Business Analyst Manager', 'A slow text field'],
93
- ['Scott', 25, 'Programmer', 'A slow text field'],
94
- ['Josh', 23, 'Supervisor', 'A slow text field'],
95
- ['Bob', 40, 'Peon', 'A slow text field']
96
- ]
97
-
98
- DMPerson.truncate!
99
-
100
- x.report('DataMapper:insert') do
101
- N.times do
102
- people.each do |a|
103
- DMPerson::create(:name => a[0], :age => a[1], :occupation => a[2], :notes => a[3])
104
- end
105
- end
106
- end
107
-
108
- x.report('DataMapper:update') do
109
- N.times do
110
- bob = DMAnimal.first(:name => 'Elephant')
111
- bob.notes = 'Updated by DataMapper'
112
- bob.save
113
- end
114
- end
115
-
116
- x.report('DataMapper:associations') do
117
- N.times do
118
- Zoo.all.each { |zoo| zoo.exhibits.entries }
119
- end
120
- end
121
-
122
- x.report('DataMapper:associations:in-session') do
123
- database do
124
- N.times do
125
- Zoo.all.each { |zoo| zoo.exhibits.entries }
126
- end
127
- end
128
- end
129
-
130
- x.report('DataMapper:find_by_sql') do
131
- N.times do
132
- database.query("SELECT * FROM zoos")
133
- end
134
- end
135
-
136
- x.report('DataMapper:accessors') do
137
- person = DMPerson.first
138
-
139
- N.times do
140
- <<-VCARD
141
- #{person.name} (#{person.age})
142
- #{person.occupation}
143
-
144
- #{person.street}
145
- #{person.city}, #{person.state} #{person.zip_code}
146
-
147
- #{person.notes}
148
- VCARD
149
- end
150
- end
151
-
152
-
153
- end
@@ -1,103 +0,0 @@
1
- module DataMapper
2
- module Support
3
-
4
- module ActiveRecordImpersonation
5
-
6
- def self.included(base)
7
- base.extend(ClassMethods)
8
- end
9
-
10
- def save
11
- database_context.save(self)
12
- end
13
-
14
- def reload!
15
- database_context.first(self.class, key, :select => original_values.keys, :reload => true)
16
- self.loaded_associations.each { |association| association.reload! }
17
- self
18
- end
19
-
20
- def reload
21
- reload!
22
- end
23
-
24
- def destroy!
25
- database_context.destroy(self)
26
- end
27
-
28
- module ClassMethods
29
-
30
- def find_or_create(search_attributes, create_attributes = {})
31
- first(search_attributes) || create(search_attributes.merge(create_attributes))
32
- end
33
-
34
- def all(options = {})
35
- database.all(self, options)
36
- end
37
-
38
- def each(options = {}, &b)
39
- raise ArgumentError.new(":offset is not supported with the #each method") if options.has_key?(:offset)
40
-
41
- offset = 0
42
- limit = options[:limit] || (self::const_defined?('DEFAULT_LIMIT') ? self::DEFAULT_LIMIT : 500)
43
-
44
- until (results = all(options.merge(:limit => limit, :offset => offset))).empty?
45
- results.each(&b)
46
- offset += limit
47
- end
48
- end
49
-
50
- def first(*args)
51
- database.first(self, *args)
52
- end
53
-
54
- def count(*args)
55
- database.count(self, *args)
56
- end
57
-
58
- def delete_all
59
- database.delete_all(self)
60
- end
61
-
62
- def truncate!
63
- database.truncate(self)
64
- end
65
-
66
- def find(type_or_id, options = {})
67
- case type_or_id
68
- when :first then first(options)
69
- when :all then all(options)
70
- else first(type_or_id, options)
71
- end
72
- end
73
-
74
- def find_by_sql(*args)
75
- DataMapper::database.query(*args)
76
- end
77
-
78
- def get(*keys)
79
- database.get(self, keys)
80
- end
81
-
82
- def [](*keys)
83
- raise ArgumentError.new('Hash is not a valid key') if keys.size == 1 && keys.first.is_a?(Hash)
84
- database.get(self, keys)
85
- end
86
-
87
- def create(attributes)
88
- instance = self.new(attributes)
89
- instance.save
90
- instance
91
- end
92
-
93
- def create!(attributes)
94
- instance = self.new(attributes)
95
- instance.save
96
- raise InvalidRecord.new(instance) if instance.new_record?
97
- instance
98
- end
99
- end
100
- end
101
-
102
- end
103
- end
@@ -1,46 +0,0 @@
1
- module DataMapper
2
- module Support
3
- class WeakHash
4
- attr_reader :cache
5
- def initialize( cache = Hash.new )
6
- @cache = cache
7
- @key_map = {}
8
- @rev_cache = Hash.new{|h,k| h[k] = {}}
9
- @reclaim_value = lambda do |value_id|
10
- if @rev_cache.has_key? value_id
11
- @rev_cache[value_id].each_key{|key| @cache.delete key}
12
- @rev_cache.delete value_id
13
- end
14
- end
15
- @reclaim_key = lambda do |key_id|
16
- if @key_map.has_key? key_id
17
- @cache.delete @key_map[key_id]
18
- end
19
- end
20
- end
21
-
22
- def []( key )
23
- value_id = @cache[key]
24
- return ObjectSpace._id2ref(value_id) unless value_id.nil?
25
- nil
26
- rescue RangeError
27
- nil
28
- end
29
-
30
- def []=( key, value )
31
- case key
32
- when Fixnum, Symbol, true, false
33
- key2 = key
34
- else
35
- key2 = key.dup
36
- end
37
- @rev_cache[value.object_id][key2] = true
38
- @cache[key2] = value.object_id
39
- @key_map[key.object_id] = key2
40
-
41
- ObjectSpace.define_finalizer(value, @reclaim_value)
42
- ObjectSpace.define_finalizer(key, @reclaim_key)
43
- end
44
- end # class WeakHash
45
- end # module Support
46
- end # module DataMapper
@@ -1,129 +0,0 @@
1
- require File.dirname(__FILE__) + "/spec_helper"
2
-
3
- describe DataMapper::Support::ActiveRecordImpersonation do
4
-
5
- before(:all) do
6
- fixtures(:animals)
7
- fixtures(:exhibits)
8
- end
9
-
10
- describe 'A record' do
11
- it 'should save and return true if validations pass' do
12
- count = Exhibit.count
13
- bugs_and_more_bugs = Exhibit.new(:name => 'Bugs And More Bugs')
14
- bugs_and_more_bugs.save.should be_true
15
- Exhibit.count.should == count + 1
16
- end
17
-
18
- it 'should return false on save if validations fail' do
19
- count = Exhibit.count
20
- bugs_and_more_bugs = Exhibit.new
21
- bugs_and_more_bugs.save.should be_false
22
- Exhibit.count.should == count
23
- end
24
-
25
- it 'should reload its attributes' do
26
- frog = Animal.first(:name => 'Frog')
27
- frog.name = 'MegaFrog'
28
- frog.name.should == 'MegaFrog'
29
- frog.reload!
30
- frog.name.should == 'Frog'
31
- end
32
-
33
- it "should prepare it's associations for reload" do
34
- chippy = Animal.first(:name => 'Cup')
35
- amazonia = Exhibit.first(:name => 'Amazonia')
36
- amazonia.animals << chippy
37
- amazonia.animals.should include(chippy)
38
- amazonia.reload!
39
- amazonia.animals.should_not include(chippy)
40
- end
41
-
42
- it 'should be destroyed!' do
43
- capybara = Animal.create(:name => 'Capybara')
44
- count = Animal.count
45
- capybara.destroy!
46
- Animal.first(:name => 'Capybara').should be_nil
47
- Animal.count.should == count - 1
48
- end
49
- end
50
-
51
- it 'should return the first match using find_or_create' do
52
- count = Animal.count
53
- frog = Animal.find_or_create(:name => 'Frog')
54
- frog.name.should == 'Frog'
55
- Animal.count.should == count
56
- end
57
-
58
- it 'should create a record if a match is not found with find_or_create' do
59
- count = Animal.count
60
- capybara = Animal.find_or_create(:name => 'Capybara')
61
- capybara.name.should == 'Capybara'
62
- Animal.count.should == count + 1
63
- end
64
-
65
- it 'should return all records' do
66
- all_animals = Animal.all
67
- all_animals.length.should == Animal.count
68
- all_animals.each do |animal|
69
- animal.class.should == Animal
70
- end
71
- end
72
-
73
- it 'should return the first record' do
74
- Animal.first.should == Animal.find(:first)
75
- end
76
-
77
- it 'should return a count of the records' do
78
- Animal.count.should == Animal.find_by_sql("SELECT COUNT(*) FROM animals")[0]
79
- end
80
-
81
- it 'should delete all records' do
82
- Animal.delete_all
83
- Animal.count.should == 0
84
-
85
- fixtures(:animals)
86
- end
87
-
88
- #it 'should be truncated' do
89
- # Animal.truncate!
90
- # Animal.count.should == 0
91
- #
92
- # fixtures(:animals)
93
- #end
94
-
95
- it 'should find a matching record given an id' do
96
- Animal.find(1).name.should == 'Frog'
97
- end
98
-
99
- it 'should find all records' do
100
- Animal.find(:all).length.should == Animal.count
101
- end
102
-
103
- it 'should find all matching records given some condition' do
104
- Animal.find(:all, :conditions => ["name = ?", "Frog"])[0].name.should == 'Frog'
105
- end
106
-
107
- it 'should find the first matching record' do
108
- Animal.find(:first).name.should == 'Frog'
109
- end
110
-
111
- it 'should find the first matching record given some condition' do
112
- Animal.find(:first, :conditions => ["name = ?", "Frog"]).name.should == 'Frog'
113
- end
114
-
115
- it 'should select records using the supplied sql fragment' do
116
- Animal.find_by_sql("SELECT name FROM animals WHERE name='Frog'")[0].should == 'Frog'
117
- end
118
-
119
- it 'should retrieve the indexed element' do
120
- Animal[1].id.should == 1
121
- end
122
-
123
- it 'should create a new record' do
124
- count = Animal.count
125
- capybara = Animal.create(:name => 'Capybara')
126
- capybara.name.should == 'Capybara'
127
- Animal.count.should == count + 1
128
- end
129
- end
@@ -1,232 +0,0 @@
1
- require File.dirname(__FILE__) + "/spec_helper"
2
-
3
- describe DataMapper::Associations::BelongsToAssociation do
4
- before(:all) do
5
- fixtures(:zoos)
6
- end
7
-
8
- before(:each) do
9
- @aviary = Exhibit.first(:name => 'Monkey Mayhem')
10
- end
11
-
12
- it 'has a zoo association' do
13
- @aviary.zoo.class.should == Zoo
14
- Exhibit.new.zoo.should == nil
15
- end
16
-
17
- it 'belongs to a zoo' do
18
- @aviary.zoo.should == @aviary.database_context.first(Zoo, :name => 'San Diego')
19
- end
20
-
21
- it "is assigned a zoo_id" do
22
- zoo = Zoo.first
23
- exhibit = Exhibit.new(:name => 'bob')
24
- exhibit.zoo = zoo
25
- exhibit.instance_variable_get("@zoo_id").should == zoo.id
26
-
27
- exhibit.save.should eql(true)
28
-
29
- zoo2 = Zoo.first
30
- zoo2.exhibits.should include(exhibit)
31
-
32
- exhibit.destroy!
33
-
34
- zoo = Zoo.new(:name => 'bob')
35
- bob = Exhibit.new(:name => 'bob')
36
- zoo.exhibits << bob
37
- zoo.save.should eql(true)
38
-
39
- zoo.exhibits.first.should_not be_a_new_record
40
-
41
- bob.destroy!
42
- zoo.destroy!
43
- end
44
-
45
- it 'can build its zoo' do
46
- database do |db|
47
- e = Exhibit.new({:name => 'Super Extra Crazy Monkey Cage'})
48
- e.zoo.should == nil
49
- e.build_zoo({:name => 'Monkey Zoo'})
50
- e.zoo.class == Zoo
51
- e.zoo.new_record?.should == true
52
-
53
- e.save
54
- end
55
- end
56
-
57
- it 'can build its zoo' do
58
- database do |db|
59
- e = Exhibit.new({:name => 'Super Extra Crazy Monkey Cage'})
60
- e.zoo.should == nil
61
- e.create_zoo({:name => 'Monkey Zoo'})
62
- e.zoo.class == Zoo
63
- e.zoo.new_record?.should == false
64
- e.save
65
- end
66
- end
67
-
68
- after(:all) do
69
- fixtures('zoos')
70
- fixtures('exhibits')
71
- end
72
- end
73
-
74
- describe DataMapper::Associations::HasAndBelongsToManyAssociation do
75
-
76
- before(:all) do
77
- fixtures(:animals)
78
- fixtures(:exhibits)
79
- end
80
-
81
- before(:each) do
82
- @amazonia = Exhibit.first :name => 'Amazonia'
83
- end
84
-
85
- it "should generate the SQL for a join statement" do
86
- animals_association = database(:mock).schema[Exhibit].associations.find { |a| a.name == :animals }
87
-
88
- animals_association.to_sql.should == <<-EOS.compress_lines
89
- JOIN `animals_exhibits` ON `animals_exhibits`.`exhibit_id` = `exhibits`.`id`
90
- JOIN `animals` ON `animals`.`id` = `animals_exhibits`.`animal_id`
91
- EOS
92
- end
93
-
94
- it "should load associations" do
95
- database do
96
- froggy = Animal.first(:name => 'Frog')
97
- froggy.exhibits.size.should == 1
98
- froggy.exhibits.entries.first.should == Exhibit.first(:name => 'Amazonia')
99
- end
100
- end
101
-
102
- it 'has an animals association' do
103
- [@amazonia, Exhibit.new].each do |exhibit|
104
- exhibit.animals.class.should == DataMapper::Associations::HasAndBelongsToManyAssociation::Set
105
- end
106
- end
107
-
108
- it 'has many animals' do
109
- @amazonia.animals.size.should == 1
110
- end
111
-
112
- it 'should load associations magically' do
113
- Exhibit.all.each do |exhibit|
114
- exhibit.animals.each do |animal|
115
- animal.exhibits.should include(exhibit)
116
- end
117
- end
118
- end
119
-
120
- it 'should allow association of additional objects' do
121
- @amazonia.animals << Animal.new(:name => "Buffalo")
122
- @amazonia.animals.size.should == 2
123
- @amazonia.reload
124
- end
125
-
126
- it "should allow association of additional objects (CLEAN)" do
127
- pending "http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/92"
128
- @amazonia.should_not be_dirty
129
-
130
- animal = Animal[2]
131
- animal.should_not be_dirty
132
-
133
- @amazonia.animals << animal
134
- @amazonia.animals.size.should == 2
135
- @amazonia.reload
136
- end
137
-
138
- it 'should allow you to fill and clear an association' do
139
- marcy = Exhibit.create(:name => 'marcy')
140
-
141
- Animal.all.each do |animal|
142
- marcy.animals << animal
143
- end
144
-
145
- marcy.save.should eql(true)
146
- marcy.should have(Animal.count).animals
147
-
148
- marcy.animals.clear
149
- marcy.should have(0).animals
150
-
151
- marcy.save.should eql(true)
152
-
153
- marcys_stand_in = Exhibit[marcy.id]
154
- marcys_stand_in.should have(0).animals
155
-
156
- marcy.destroy!
157
- end
158
-
159
- it 'should allow you to delete a specific association member' do
160
- walter = Exhibit.create(:name => 'walter')
161
-
162
- Animal.all.each do |animal|
163
- walter.animals << animal
164
- end
165
-
166
- walter.save.should eql(true)
167
- walter.should have(Animal.count).animals
168
-
169
- delete_me = walter.animals.entries.first
170
- walter.animals.delete(delete_me).should eql(delete_me)
171
- walter.animals.delete(delete_me).should eql(nil)
172
-
173
- walter.should have(Animal.count - 1).animals
174
- walter.save.should eql(true)
175
-
176
- walters_stand_in = Exhibit[walter.id]
177
- walters_stand_in.animals.size.should eql(walter.animals.size)
178
-
179
- walter.destroy!
180
- end
181
-
182
- it "should allow updates to associations using association_ids[]" do
183
- pending "Awaiting implementation of association_ids[]"
184
- meerkat = Animal.new(:name => "Meerkat")
185
- @amazonia.animals.size.should == 1
186
-
187
- @amazonia.animal_ids << meerkat.id
188
- @amazonia.save
189
-
190
- @amazonia.animals.size.should == 2
191
- @amazonia.animals.should include?(meerkat)
192
- end
193
-
194
- it "Should handle setting complementary associations" do
195
- pending("some borkage here")
196
- u1 = User.create(:name => "u1")
197
- u1.comments.should be_empty
198
-
199
- c1 = Comment.create(:comment => "c", :author => u1)
200
- # p u1
201
- # p c1
202
-
203
- u1.comments.should_not be_empty
204
- u1.comments.should include(c1)
205
-
206
- u1.reload!
207
- u1.comments.should_not be_empty
208
- u1.comments.should include(c1)
209
- end
210
-
211
- it "should raise an error when attempting to associate an object not of the correct type (assuming added model doesn't inherit from the correct type)" do
212
- pending("see: http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/91")
213
- @amazonia.animals.should_not be_empty
214
- chuck = Person.new(:name => "Chuck")
215
-
216
- ## InvalidRecord isn't the error we should use here....needs to be changed
217
- lambda { @amazonia.animals << chuck }.should raise_error(WrongType)
218
-
219
- end
220
-
221
- it "should associate an object which has inherited from the correct type into an association" do
222
- pending("see: http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/91")
223
- programmer = Career.first(:name => 'Programmer')
224
- programmer.followers.should_not be_empty
225
-
226
- sales_person = SalesPerson.new(:name => 'Chuck')
227
-
228
- lambda { programmer.followers << sales_person }.should_not raise_error(WrongType)
229
-
230
- end
231
-
232
- end