perpetuity 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## Version 0.6.0
2
+
3
+ - Stop extending persisted/retrieved objects with `Perpetuity::PersistedObject`. Extending these objects invalidates method caches inside the VM, which degrades performance.
4
+ - Cache all objects returned from `Mapper#find(id)` by default into the mapper object. This can be bypassed with `Mapper#find(id, false)`
5
+ - Do not store uninitialized attributes with the MongoDB serializer. This shrinks the size of documents when possible.
6
+
1
7
  ## Version 0.5.0
2
8
 
3
9
  - Allow querying based on referenced class/id or embedded-object data
@@ -1,5 +1,3 @@
1
- require 'perpetuity/persisted_object'
2
-
3
1
  module Perpetuity
4
2
  module DataInjectable
5
3
  def inject_attribute object, attribute, value
@@ -17,7 +15,6 @@ module Perpetuity
17
15
  if args.any?
18
16
  inject_attribute object, :id, args.first
19
17
  end
20
- object.extend PersistedObject
21
18
  end
22
19
  end
23
20
  end
@@ -7,11 +7,13 @@ module Perpetuity
7
7
  end
8
8
 
9
9
  def [] klass, id
10
- map[klass][id]
10
+ map[klass][id.to_s]
11
11
  end
12
12
 
13
13
  def << object
14
- map[object.class][object.id] = object
14
+ klass = object.class
15
+ id = object.instance_variable_get(:@id)
16
+ map[klass][id.to_s] = object
15
17
  end
16
18
  end
17
19
  end
@@ -8,10 +8,11 @@ require 'perpetuity/retrieval'
8
8
  module Perpetuity
9
9
  class Mapper
10
10
  include DataInjectable
11
- attr_reader :mapper_registry
11
+ attr_reader :mapper_registry, :identity_map
12
12
 
13
13
  def initialize registry=Perpetuity.mapper_registry
14
14
  @mapper_registry = registry
15
+ @identity_map = IdentityMap.new
15
16
  end
16
17
 
17
18
  def self.map klass, registry=Perpetuity.mapper_registry
@@ -106,12 +107,20 @@ module Perpetuity
106
107
 
107
108
  alias :find_all :select
108
109
 
109
- def find *args, &block
110
+ def find id=nil, cache_result=true, &block
110
111
  if block_given?
111
112
  select(&block).first
112
113
  else
113
- id = args.first
114
- select { |object| object.id == id }.first
114
+ cached_value = identity_map[mapped_class, id]
115
+ return cached_value if cached_value
116
+
117
+ result = select { |object| object.id == id }.first
118
+
119
+ if cache_result and !result.nil?
120
+ identity_map << result
121
+ end
122
+
123
+ result
115
124
  end
116
125
  end
117
126
 
@@ -122,7 +131,7 @@ module Perpetuity
122
131
  end
123
132
 
124
133
  def delete object
125
- id = object.is_a?(PersistedObject) ? object.id : object
134
+ id = persisted?(object) ? id_for(object) : object
126
135
  data_source.delete id, mapped_class
127
136
  end
128
137
 
@@ -152,7 +161,7 @@ module Perpetuity
152
161
  end
153
162
 
154
163
  def update object, new_data, update_in_memory = true
155
- id = object.is_a?(mapped_class) ? object.id : object
164
+ id = object.is_a?(mapped_class) ? id_for(object) : object
156
165
 
157
166
  inject_data object, new_data if update_in_memory
158
167
  data_source.update mapped_class, id, new_data
@@ -163,17 +172,25 @@ module Perpetuity
163
172
  end
164
173
 
165
174
  def increment object, attribute, count=1
166
- data_source.increment mapped_class, object.id, attribute, count
175
+ data_source.increment mapped_class, id_for(object), attribute, count
167
176
  rescue Moped::Errors::OperationFailure
168
177
  raise ArgumentError.new('Attempted to increment a non-numeric value')
169
178
  end
170
179
 
171
180
  def decrement object, attribute, count=1
172
- data_source.increment mapped_class, object.id, attribute, -count
181
+ data_source.increment mapped_class, id_for(object), attribute, -count
173
182
  rescue Moped::Errors::OperationFailure
174
183
  raise ArgumentError.new('Attempted to decrement a non-numeric value')
175
184
  end
176
185
 
186
+ def persisted? object
187
+ object.instance_variable_defined?(:@id)
188
+ end
189
+
190
+ def id_for object
191
+ object.instance_variable_get(:@id)
192
+ end
193
+
177
194
  def self.validate &block
178
195
  validations.instance_exec(&block)
179
196
  end
@@ -17,8 +17,14 @@ module Perpetuity
17
17
  object.instance_variable_get("@#{attribute_name}")
18
18
  end
19
19
 
20
+ def has_attribute? object, attribute_name
21
+ object.instance_variable_defined? "@#{attribute_name}"
22
+ end
23
+
20
24
  def serialize object
21
25
  attrs = mapper.class.attribute_set.map do |attrib|
26
+ next unless has_attribute? object, attrib.name
27
+
22
28
  value = attribute_for object, attrib.name
23
29
 
24
30
  serialized_value = if value.is_a? Reference
@@ -36,7 +42,7 @@ module Perpetuity
36
42
  [attrib.name.to_s, serialized_value]
37
43
  end
38
44
 
39
- Hash[attrs]
45
+ Hash[attrs.compact]
40
46
  end
41
47
 
42
48
  def unserialize data
@@ -134,10 +140,10 @@ module Perpetuity
134
140
  if value.is_a? Reference
135
141
  reference = value
136
142
  else
137
- unless value.is_a? PersistedObject
143
+ unless mapper.persisted? value
138
144
  mapper_registry[value.class].insert value
139
145
  end
140
- reference = Reference.new(value.class.to_s, value.id)
146
+ reference = Reference.new(value.class.to_s, mapper.id_for(value))
141
147
  end
142
148
  {
143
149
  '__metadata__' => {
@@ -7,11 +7,15 @@ module Perpetuity
7
7
  end
8
8
 
9
9
  def == other
10
- klass == other.klass && id == other.id
10
+ if other.is_a? self.class
11
+ klass == other.klass && id == other.id
12
+ else
13
+ other.is_a?(klass) && id == other.id
14
+ end
11
15
  end
12
16
 
13
17
  def eql? other
14
- self == other
18
+ other.is_a?(self.class) && self == other
15
19
  end
16
20
  end
17
21
  end
@@ -1,3 +1,3 @@
1
1
  module Perpetuity
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/perpetuity.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "perpetuity/version"
2
- require "perpetuity/retrieval"
3
2
  require "perpetuity/mongodb"
4
3
  require "perpetuity/config"
5
4
  require "perpetuity/mapper"
@@ -17,16 +17,16 @@ describe 'associations with other objects' do
17
17
  end
18
18
 
19
19
  describe 'referenced relationships' do
20
- let(:creator) { topic_mapper.find(topic.id).creator }
20
+ let(:creator) { topic_mapper.find(topic_mapper.id_for topic).creator }
21
21
  subject { creator }
22
22
 
23
23
  it { should be_a Perpetuity::Reference }
24
24
  its(:klass) { should be User }
25
- its(:id) { should be == user.id }
25
+ its(:id) { should be == user_mapper.id_for(user) }
26
26
  end
27
27
 
28
28
  it 'can retrieve a one-to-one association' do
29
- retrieved_topic = topic_mapper.find(topic.id)
29
+ retrieved_topic = topic_mapper.find(topic_mapper.id_for topic)
30
30
 
31
31
  topic_mapper.load_association! retrieved_topic, :creator
32
32
  retrieved_topic.creator.name.should eq 'Flump'
@@ -45,7 +45,7 @@ describe 'associations with other objects' do
45
45
  end
46
46
 
47
47
  it 'can retrieve a one-to-many association' do
48
- persisted_book = book_mapper.find(pragprog_book.id)
48
+ persisted_book = book_mapper.find(book_mapper.id_for pragprog_book)
49
49
  book_mapper.load_association! persisted_book, :authors
50
50
 
51
51
  persisted_book.authors.first.name.should be == 'Dave'
@@ -55,7 +55,7 @@ describe 'associations with other objects' do
55
55
  it 'can retrieve a many-to-many association' do
56
56
  cuke_authors.each { |author| Perpetuity[User].insert author }
57
57
  book_mapper.insert cuke_book
58
- book_ids = [pragprog_book, cuke_book].map(&:id)
58
+ book_ids = [pragprog_book, cuke_book].map { |book| book_mapper.id_for(book) }
59
59
 
60
60
  books = book_mapper.select { |book| book.id.in book_ids }.to_a
61
61
  book_mapper.load_association! books, :authors
@@ -70,7 +70,7 @@ describe 'associations with other objects' do
70
70
  mapper = Perpetuity[Article]
71
71
 
72
72
  mapper.insert article
73
- retrieved = mapper.find(article.id)
73
+ retrieved = mapper.find(mapper.id_for(article))
74
74
  mapper.load_association! retrieved, :author
75
75
  retrieved.author.should == [foo, bar]
76
76
  end
@@ -90,7 +90,8 @@ describe 'associations with other objects' do
90
90
 
91
91
  it 'serializes attributes' do
92
92
  mapper.insert object
93
- mapper.find(object.id).embedded_attribute.should be == [unserializable_object]
93
+ attr = mapper.find(mapper.id_for object).embedded_attribute
94
+ attr.should be == [unserializable_object]
94
95
  end
95
96
  end
96
97
  end
@@ -14,7 +14,12 @@ describe 'indexing' do
14
14
  index.attribute.to_s == :name
15
15
  end
16
16
  end
17
+ let(:db_name) { Perpetuity.configuration.data_source.db }
17
18
 
19
+ before do
20
+ Perpetuity.data_source :mongodb, db_name
21
+ mapper.data_source.drop_collection Object
22
+ end
18
23
  after { mapper.data_source.drop_collection Object }
19
24
 
20
25
  it 'adds indexes to database collections/tables' do
@@ -125,6 +125,7 @@ module Perpetuity
125
125
  end
126
126
 
127
127
  it 'creates indexes on the database collection' do
128
+ mongo.delete_all collection
128
129
  index = mongo.index collection, 'real_index', order: :descending, unique: true
129
130
  mongo.activate_index! index
130
131
 
@@ -132,6 +133,7 @@ module Perpetuity
132
133
  end
133
134
 
134
135
  it 'removes indexes' do
136
+ mongo.drop_collection collection
135
137
  index = mongo.index collection, 'real_index', order: :descending, unique: true
136
138
  mongo.activate_index! index
137
139
  mongo.remove_index index
@@ -156,7 +158,11 @@ module Perpetuity
156
158
  let(:data) { { foo: 'bar' } }
157
159
  let(:index) { mongo.index Object, :foo, unique: true }
158
160
 
159
- before { mongo.activate_index! index }
161
+ before do
162
+ mongo.delete_all Object
163
+ mongo.activate_index! index
164
+ end
165
+
160
166
  after { mongo.drop_collection Object }
161
167
 
162
168
  it 'raises an exception when insertion fails' do
@@ -2,56 +2,61 @@ require 'spec_helper'
2
2
  require 'support/test_classes'
3
3
 
4
4
  describe 'Persistence' do
5
+ let(:mapper) { Perpetuity[Article] }
6
+
5
7
  it "persists an object" do
6
8
  article = Article.new 'I have a title'
7
- expect { Perpetuity[Article].insert article }.
8
- to change { Perpetuity[Article].count }.by 1
9
- Perpetuity[Article].find(article.id).title.should eq 'I have a title'
9
+ expect { mapper.insert article }.
10
+ to change { mapper.count }.by 1
11
+ mapper.find(mapper.id_for(article)).title.should eq 'I have a title'
10
12
  end
11
13
 
12
14
  it 'returns the id of the persisted object' do
13
15
  article = Article.new
14
- Perpetuity[Article].insert(article).should eq article.id
16
+ mapper.insert(article).should eq mapper.id_for(article)
15
17
  end
16
18
 
17
19
  it "gives an id to objects" do
18
20
  article = Article.new
19
- Perpetuity[Article].give_id_to article, 1
21
+ mapper.give_id_to article, 1
20
22
 
21
- article.id.should eq 1
23
+ mapper.id_for(article).should eq 1
22
24
  end
23
25
 
24
26
  it 'persists referenced objects if they are not persisted' do
25
27
  article = Article.new
26
28
  article.author = User.new
27
- Perpetuity[Article].insert article
29
+ mapper.insert article
28
30
 
29
- Perpetuity[Article].find(article.id).author.id.should be == article.author.id
31
+ retrieved = mapper.find(mapper.id_for(article))
32
+ mapper.id_for(retrieved.author).should be == mapper.id_for(article.author)
30
33
  end
31
34
 
32
35
  it 'persists arrays of referenced objects if they are not persisted' do
33
36
  authors = [User.new('Dave'), User.new('Andy')]
34
37
  book = Book.new
35
38
  book.authors = authors
36
- Perpetuity[Book].insert book
39
+ mapper = Perpetuity[Book]
40
+ mapper.insert book
37
41
 
38
- Perpetuity[Book].find(book.id).authors.first.id.should be == authors.first.id
42
+ first_author = mapper.find(mapper.id_for book).authors.first
43
+ mapper.id_for(first_author).should be == mapper.id_for(authors.first)
39
44
  end
40
45
 
41
46
  describe 'id injection' do
42
47
  let(:article) { Article.new }
43
48
 
44
49
  it 'assigns an id to the inserted object' do
45
- Perpetuity[Article].insert article
46
- article.should respond_to :id
50
+ mapper.insert article
51
+ mapper.id_for(article).should_not be_nil
47
52
  end
48
53
 
49
54
  it "assigns an id using Mapper.first" do
50
- Perpetuity[Article].first.should respond_to :id
55
+ mapper.id_for(mapper.first).should_not be_nil
51
56
  end
52
57
 
53
58
  it 'assigns an id using Mapper.all.first' do
54
- Perpetuity[Article].all.first.should respond_to :id
59
+ mapper.id_for(mapper.all.first).should_not be_nil
55
60
  end
56
61
  end
57
62
 
@@ -60,18 +65,17 @@ describe 'Persistence' do
60
65
 
61
66
  it 'persists arrays' do
62
67
  article.comments << 1 << 2 << 3
63
- Perpetuity[Article].insert article
64
- Perpetuity[Article].find(article.id).comments.should eq [1, 2, 3]
68
+ mapper.insert article
69
+ mapper.find(mapper.id_for article).comments.should eq [1, 2, 3]
65
70
  end
66
71
 
67
72
  it 'persists arrays with unserializable objects in them' do
68
73
  comment = Comment.new('my comment')
69
74
  article.comments << comment
70
- Perpetuity[Article].insert article
71
- Perpetuity[Article].find(article.id).comments.first.tap do |persisted_comment|
72
- persisted_comment.should be_a Comment
73
- persisted_comment.body.should eq comment.body
74
- end
75
+ mapper.insert article
76
+ persisted_comment = mapper.find(mapper.id_for article).comments.first
77
+ persisted_comment.should be_a Comment
78
+ persisted_comment.body.should eq comment.body
75
79
  end
76
80
  end
77
81
 
@@ -82,7 +86,7 @@ describe 'Persistence' do
82
86
 
83
87
  it 'saves and retrieves hashes' do
84
88
  user_mapper.insert user
85
- user_mapper.find(user.id).name.should be == name_hash
89
+ user_mapper.find(user_mapper.id_for user).name.should be == name_hash
86
90
  end
87
91
  end
88
92
 
@@ -91,7 +95,7 @@ describe 'Persistence' do
91
95
  book = Book.new("My Title #{noise}")
92
96
 
93
97
  Perpetuity[Book].insert book
94
- book.id.should eq "my-title-#{noise}"
98
+ Perpetuity[Book].id_for(book).should eq "my-title-#{noise}"
95
99
  end
96
100
 
97
101
  context 'with namespaced classes' do
@@ -102,7 +106,7 @@ describe 'Persistence' do
102
106
 
103
107
  it 'persists even with colons in the names' do
104
108
  mapper.insert person
105
- person.should be_a Perpetuity::PersistedObject
109
+ mapper.persisted?(person).should be_true
106
110
  end
107
111
  end
108
112
  end
@@ -4,23 +4,17 @@ require 'securerandom'
4
4
 
5
5
  describe "retrieval" do
6
6
  let(:mapper) { Perpetuity[Article] }
7
-
8
7
  it "gets all the objects of a class" do
9
8
  expect { mapper.insert Article.new }.
10
9
  to change { mapper.all.to_a.count }.by 1
11
10
  end
12
11
 
13
- it "has an ID when retrieved" do
14
- mapper.insert Article.new
15
- mapper.first.should respond_to :id
16
- end
17
-
18
12
  it "gets an item with a specific ID" do
19
13
  article = Article.new
20
14
  mapper.insert article
21
- retrieved = mapper.find(article.id)
15
+ retrieved = mapper.find(mapper.id_for article)
22
16
 
23
- retrieved.id.should eq article.id
17
+ mapper.id_for(retrieved).should be == mapper.id_for(article)
24
18
  retrieved.title.should eq article.title
25
19
  retrieved.body.should eq article.body
26
20
  end
@@ -61,6 +55,10 @@ describe "retrieval" do
61
55
  describe "Array-like syntax" do
62
56
  let(:draft) { Article.new 'Draft', 'draft content', nil, Time.now + 30 }
63
57
  let(:published) { Article.new 'Published', 'content', nil, Time.now - 30, 3 }
58
+
59
+ let(:published_id) { mapper.id_for published }
60
+ let(:draft_id) { mapper.id_for draft }
61
+
64
62
  before do
65
63
  mapper.insert draft
66
64
  mapper.insert published
@@ -68,57 +66,58 @@ describe "retrieval" do
68
66
 
69
67
  it 'selects objects using equality' do
70
68
  selected = mapper.select { |article| article.title == 'Published' }
71
- selected.map(&:id).should include published.id
72
- selected.map(&:id).should_not include draft.id
69
+ ids = selected.map { |article| mapper.id_for article }
70
+ ids.should include published_id
71
+ ids.should_not include draft_id
73
72
  end
74
73
 
75
74
  it 'selects objects using greater-than' do
76
75
  selected = mapper.select { |article| article.published_at < Time.now }
77
- ids = selected.map(&:id)
78
- ids.should include published.id
79
- ids.should_not include draft.id
76
+ ids = selected.map { |article| mapper.id_for article }
77
+ ids.should include published_id
78
+ ids.should_not include draft_id
80
79
  end
81
80
 
82
81
  it 'selects objects using greater-than-or-equal' do
83
82
  selected = mapper.select { |article| article.views >= 3 }
84
- ids = selected.map(&:id)
85
- ids.should include published.id
86
- ids.should_not include draft.id
83
+ ids = selected.map { |article| mapper.id_for article }
84
+ ids.should include published_id
85
+ ids.should_not include draft_id
87
86
  end
88
87
 
89
88
  it 'selects objects using less-than' do
90
89
  selected = mapper.select { |article| article.views < 3 }
91
- ids = selected.map(&:id)
92
- ids.should include draft.id
93
- ids.should_not include published.id
90
+ ids = selected.map { |article| mapper.id_for article }
91
+ ids.should include draft_id
92
+ ids.should_not include published_id
94
93
  end
95
94
 
96
95
  it 'selects objects using less-than-or-equal' do
97
96
  selected = mapper.select { |article| article.views <= 0 }
98
- ids = selected.map(&:id)
99
- ids.should include draft.id
100
- ids.should_not include published.id
97
+ ids = selected.map { |article| mapper.id_for article }
98
+ ids.should include draft_id
99
+ ids.should_not include published_id
101
100
  end
102
101
 
103
102
  it 'selects objects using inequality' do
104
103
  selected = mapper.select { |article| article.title != 'Draft' }
105
- ids = selected.map(&:id)
106
- ids.should_not include draft.id
107
- ids.should include published.id
104
+ ids = selected.map { |article| mapper.id_for article }
105
+ ids.should_not include draft_id
106
+ ids.should include published_id
108
107
  end
109
108
 
110
109
  it 'selects objects using regular expressions' do
111
110
  selected = mapper.select { |article| article.title =~ /Pub/ }
112
- ids = selected.map(&:id)
113
- ids.should include published.id
114
- ids.should_not include draft.id
111
+ ids = selected.map { |article| mapper.id_for article }
112
+ ids.should include published_id
113
+ ids.should_not include draft_id
115
114
  end
116
115
 
117
116
  it 'selects objects using inclusion' do
118
117
  selected = mapper.select { |article| article.title.in %w( Published ) }
119
- ids = selected.map(&:id)
120
- ids.should include published.id
121
- ids.should_not include draft.id
118
+ ids = selected.map { |article| mapper.id_for article }
119
+ ids.should include published_id
120
+ ids.should_not include draft_id
122
121
  end
123
122
  end
124
123
 
@@ -171,7 +170,7 @@ describe "retrieval" do
171
170
 
172
171
  it 'gets a CRM::Person object back' do
173
172
  mapper.insert article
174
- retrieved_article = mapper.find(article.id)
173
+ retrieved_article = mapper.find(mapper.id_for article)
175
174
  mapper.load_association! retrieved_article, :author
176
175
  retrieved_article.author.should be_a CRM::Person
177
176
  end
@@ -181,6 +180,8 @@ describe "retrieval" do
181
180
  user = User.new(first_name: 'foo', last_name: 'bar')
182
181
  mapper = Perpetuity[User]
183
182
  mapper.insert user
184
- mapper.select { |user| user.name.first_name == 'foo' }.map(&:id).should include user.id
183
+ users = mapper.select { |user| user.name.first_name == 'foo' }
184
+ ids = users.map { |retrieved_user| mapper.id_for(retrieved_user) }
185
+ ids.should include mapper.id_for(user)
185
186
  end
186
187
  end
@@ -13,7 +13,7 @@ describe 'serialization' do
13
13
  'author' => {
14
14
  '__metadata__' => {
15
15
  'class' => author.class.to_s,
16
- 'id' => author.id
16
+ 'id' => mapper.id_for(author)
17
17
  }
18
18
  },
19
19
  'comments' => [
@@ -25,7 +25,7 @@ describe 'serialization' do
25
25
  'author' => {
26
26
  '__metadata__' => {
27
27
  'class' => author.class.to_s,
28
- 'id' => author.id
28
+ 'id' => mapper.id_for(author)
29
29
  }
30
30
  }
31
31
  },
@@ -49,7 +49,7 @@ describe 'serialization' do
49
49
  end
50
50
 
51
51
  it 'deserializes hashes into proper objects' do
52
- unserialized = mapper.find article.id
52
+ unserialized = mapper.find mapper.id_for(article)
53
53
  unserialized.should be_a Article
54
54
  unserialized.title.should be == article.title
55
55
  unserialized.body.should be == article.body
@@ -12,7 +12,7 @@ describe 'updating' do
12
12
 
13
13
  it 'updates an object in the database' do
14
14
  mapper.update article, title: new_title
15
- mapper.find(article.id).title.should eq new_title
15
+ mapper.find(mapper.id_for article).title.should eq new_title
16
16
  end
17
17
 
18
18
  it 'updates the object in memory' do
@@ -23,7 +23,7 @@ describe 'updating' do
23
23
  it 'resaves the object in the database' do
24
24
  article.title = new_title
25
25
  mapper.save article
26
- mapper.find(article.id).title.should eq new_title
26
+ mapper.find(mapper.id_for article).title.should eq new_title
27
27
  end
28
28
 
29
29
  it 'updates an object with referenced attributes' do
@@ -31,11 +31,11 @@ describe 'updating' do
31
31
  article.author = user
32
32
  mapper.save article
33
33
 
34
- retrieved_article = mapper.find(article.id)
34
+ retrieved_article = mapper.find(mapper.id_for article)
35
35
  retrieved_article.title = new_title
36
36
  mapper.save retrieved_article
37
37
 
38
- retrieved_article = mapper.find(retrieved_article.id)
38
+ retrieved_article = mapper.find(mapper.id_for retrieved_article)
39
39
  retrieved_article.author.should be_a Perpetuity::Reference
40
40
  end
41
41
 
@@ -48,13 +48,13 @@ describe 'updating' do
48
48
 
49
49
  mapper.insert book
50
50
 
51
- retrieved_book = mapper.find(book.id)
51
+ retrieved_book = mapper.find(mapper.id_for book)
52
52
  retrieved_book.authors << andy
53
53
  mapper.save retrieved_book
54
54
 
55
- retrieved_authors = mapper.find(retrieved_book.id).authors
55
+ retrieved_authors = Perpetuity[Book].find(mapper.id_for retrieved_book).authors
56
56
  retrieved_authors.map(&:klass).should == [User, User]
57
- retrieved_authors.map(&:id).should == [dave.id, andy.id]
57
+ retrieved_authors.map(&:id).should == [mapper.id_for(dave), mapper.id_for(andy)]
58
58
  end
59
59
 
60
60
  describe 'atomic increments/decrements' do
@@ -64,13 +64,13 @@ describe 'updating' do
64
64
  it 'increments attributes of objects in the database' do
65
65
  mapper.increment article, :views
66
66
  mapper.increment article, :views, 10
67
- mapper.find(article.id).views.should == view_count + 11
67
+ mapper.find(mapper.id_for(article)).views.should == view_count + 11
68
68
  end
69
69
 
70
70
  it 'decrements attributes of objects in the database' do
71
71
  mapper.decrement article, :views
72
72
  mapper.decrement article, :views, 10
73
- mapper.find(article.id).views.should == view_count - 11
73
+ mapper.find(mapper.id_for(article)).views.should == view_count - 11
74
74
  end
75
75
 
76
76
  context 'with an object with the specified attribute missing' do
@@ -20,12 +20,12 @@ module Perpetuity
20
20
 
21
21
  it 'injects an id' do
22
22
  klass.inject_data object, { id: 1 }
23
- object.id.should eq 1
23
+ object.instance_variable_get(:@id).should eq 1
24
24
  end
25
25
 
26
26
  it 'injects a specified id' do
27
27
  klass.give_id_to object, 2
28
- object.id.should eq 2
28
+ object.instance_variable_get(:@id).should eq 2
29
29
  end
30
30
  end
31
31
  end