remodel 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -4
- data/VERSION +1 -1
- data/example/book.rb +1 -2
- data/lib/remodel/entity.rb +30 -36
- data/lib/remodel/has_many.rb +6 -32
- data/test/test_has_many.rb +105 -0
- data/test/test_has_one.rb +68 -0
- data/test/test_inheritance.rb +65 -0
- data/test/test_shortnames.rb +73 -0
- metadata +12 -16
- data/docs/docco.css +0 -185
- data/docs/remodel.html +0 -269
- data/test/test_entity_shortnames.rb +0 -36
- data/test/test_many_to_many.rb +0 -77
- data/test/test_many_to_one.rb +0 -117
- data/test/test_one_to_many.rb +0 -96
- data/test/test_one_to_one.rb +0 -57
data/README.md
CHANGED
@@ -51,14 +51,13 @@ persistence to disk. for example, on my macbook (2 ghz):
|
|
51
51
|
define your domain model [like this](http://github.com/tlossen/remodel/blob/master/example/book.rb):
|
52
52
|
|
53
53
|
class Book < Remodel::Entity
|
54
|
-
has_many :chapters, :class => 'Chapter'
|
54
|
+
has_many :chapters, :class => 'Chapter'
|
55
55
|
property :title, :short => 't', :class => 'String'
|
56
56
|
property :year, :class => 'Integer'
|
57
57
|
property :author, :class => 'String', :default => '(anonymous)'
|
58
58
|
end
|
59
59
|
|
60
60
|
class Chapter < Remodel::Entity
|
61
|
-
has_one :book, :class => Book, :reverse => :chapters
|
62
61
|
property :title, :class => String
|
63
62
|
end
|
64
63
|
|
@@ -72,8 +71,6 @@ now you can do:
|
|
72
71
|
=> #<Book(shelf, 1) title: "Moby Dick", year: 1851, author: "(anonymous)">
|
73
72
|
>> chapter = book.chapters.create :title => 'Ishmael'
|
74
73
|
=> #<Chapter(shelf, 1) title: "Ishmael">
|
75
|
-
>> chapter.book
|
76
|
-
=> #<Book(shelf, 1) title: "Moby Dick", year: 1851, author: "(anonymous)">
|
77
74
|
|
78
75
|
all entities have been created in the redis hash 'shelf' we have used as context:
|
79
76
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/example/book.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../lib/remodel"
|
2
2
|
|
3
3
|
class Book < Remodel::Entity
|
4
|
-
has_many :chapters, :class => 'Chapter'
|
4
|
+
has_many :chapters, :class => 'Chapter'
|
5
5
|
property :title, :short => 't', :class => 'String'
|
6
6
|
property :year, :class => 'Integer'
|
7
7
|
property :author, :class => 'String', :default => '(anonymous)'
|
8
8
|
end
|
9
9
|
|
10
10
|
class Chapter < Remodel::Entity
|
11
|
-
has_one :book, :class => Book, :reverse => :chapters
|
12
11
|
property :title, :class => String
|
13
12
|
end
|
14
13
|
|
data/lib/remodel/entity.rb
CHANGED
@@ -82,7 +82,7 @@ module Remodel
|
|
82
82
|
|
83
83
|
def self.property(name, options = {})
|
84
84
|
name = name.to_sym
|
85
|
-
|
85
|
+
_mapper[name] = Remodel.mapper_for(options[:class])
|
86
86
|
define_shortname(name, options[:short])
|
87
87
|
default_value = options[:default]
|
88
88
|
define_method(name) { @attributes[name].nil? ? self.class.copy_of(default_value) : @attributes[name] }
|
@@ -90,68 +90,44 @@ module Remodel
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def self.has_many(name, options)
|
93
|
-
|
93
|
+
_associations.push(name)
|
94
94
|
var = "@#{name}".to_sym
|
95
|
+
shortname = options[:short] || name
|
95
96
|
|
96
97
|
define_method(name) do
|
97
98
|
if instance_variable_defined? var
|
98
99
|
instance_variable_get(var)
|
99
100
|
else
|
100
101
|
clazz = Class[options[:class]]
|
101
|
-
instance_variable_set(var, HasMany.new(self, clazz, "#{key}_#{
|
102
|
+
instance_variable_set(var, HasMany.new(self, clazz, "#{key}_#{shortname}"))
|
102
103
|
end
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
106
107
|
def self.has_one(name, options)
|
107
|
-
|
108
|
+
_associations.push(name)
|
108
109
|
var = "@#{name}".to_sym
|
110
|
+
shortname = options[:short] || name
|
109
111
|
|
110
112
|
define_method(name) do
|
111
113
|
if instance_variable_defined? var
|
112
114
|
instance_variable_get(var)
|
113
115
|
else
|
114
116
|
clazz = Class[options[:class]]
|
115
|
-
value_key = self.context.hget("#{key}_#{
|
117
|
+
value_key = self.context.hget("#{key}_#{shortname}")
|
116
118
|
value = value_key && clazz.find(self.context, value_key) rescue nil
|
117
119
|
instance_variable_set(var, value)
|
118
120
|
end
|
119
121
|
end
|
120
122
|
|
121
123
|
define_method("#{name}=") do |value|
|
122
|
-
send("_reverse_association_of_#{name}=", value) if options[:reverse]
|
123
|
-
send("_#{name}=", value)
|
124
|
-
end
|
125
|
-
|
126
|
-
define_method("_#{name}=") do |value|
|
127
124
|
if value
|
128
125
|
instance_variable_set(var, value)
|
129
|
-
self.context.hset("#{key}_#{
|
126
|
+
self.context.hset("#{key}_#{shortname}", value.key)
|
130
127
|
else
|
131
128
|
remove_instance_variable(var) if instance_variable_defined? var
|
132
|
-
self.context.hdel("#{key}_#{
|
129
|
+
self.context.hdel("#{key}_#{shortname}")
|
133
130
|
end
|
134
|
-
end; private "_#{name}="
|
135
|
-
|
136
|
-
if options[:reverse]
|
137
|
-
define_method("_reverse_association_of_#{name}=") do |value|
|
138
|
-
if old_value = send(name)
|
139
|
-
association = old_value.send("#{options[:reverse]}")
|
140
|
-
if association.is_a? HasMany
|
141
|
-
association.send("_remove", self)
|
142
|
-
else
|
143
|
-
old_value.send("_#{options[:reverse]}=", nil)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
if value
|
147
|
-
association = value.send("#{options[:reverse]}")
|
148
|
-
if association.is_a? HasMany
|
149
|
-
association.send("_add", self)
|
150
|
-
else
|
151
|
-
value.send("_#{options[:reverse]}=", self)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end; private "_reverse_association_of_#{name}="
|
155
131
|
end
|
156
132
|
end
|
157
133
|
|
@@ -211,24 +187,42 @@ module Remodel
|
|
211
187
|
def self.define_shortname(name, short)
|
212
188
|
return unless short
|
213
189
|
short = short.to_sym
|
214
|
-
|
215
|
-
|
190
|
+
_shortname[name] = short
|
191
|
+
_fullname[short] = name
|
216
192
|
end
|
217
193
|
|
218
|
-
# class instance variables
|
194
|
+
# class instance variables:
|
195
|
+
# lazy init + recursive lookup in superclasses
|
196
|
+
|
219
197
|
def self.mapper
|
198
|
+
self == Entity || superclass == Entity ? _mapper : superclass.mapper.merge(_mapper)
|
199
|
+
end
|
200
|
+
|
201
|
+
def self._mapper
|
220
202
|
@mapper ||= {}
|
221
203
|
end
|
222
204
|
|
223
205
|
def self.shortname
|
206
|
+
self == Entity || superclass == Entity ? _shortname : superclass.shortname.merge(_shortname)
|
207
|
+
end
|
208
|
+
|
209
|
+
def self._shortname
|
224
210
|
@shortname ||= {}
|
225
211
|
end
|
226
212
|
|
227
213
|
def self.fullname
|
214
|
+
self == Entity || superclass == Entity ? _fullname : superclass.fullname.merge(_fullname)
|
215
|
+
end
|
216
|
+
|
217
|
+
def self._fullname
|
228
218
|
@fullname ||= {}
|
229
219
|
end
|
230
220
|
|
231
221
|
def self.associations
|
222
|
+
self == Entity || superclass == Entity ? _associations : superclass.associations + _associations
|
223
|
+
end
|
224
|
+
|
225
|
+
def self._associations
|
232
226
|
@associations ||= []
|
233
227
|
end
|
234
228
|
|
data/lib/remodel/has_many.rb
CHANGED
@@ -2,9 +2,9 @@ module Remodel
|
|
2
2
|
|
3
3
|
# Represents the many-end of a many-to-one or many-to-many association.
|
4
4
|
class HasMany < Array
|
5
|
-
def initialize(this, clazz, key
|
5
|
+
def initialize(this, clazz, key)
|
6
6
|
super _fetch(clazz, this.context, key)
|
7
|
-
@this, @clazz, @key
|
7
|
+
@this, @clazz, @key = this, clazz, key
|
8
8
|
end
|
9
9
|
|
10
10
|
def create(attributes = {})
|
@@ -16,51 +16,25 @@ module Remodel
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def add(entity)
|
19
|
-
_add_to_reverse_association_of(entity) if @reverse
|
20
|
-
_add(entity)
|
21
|
-
end
|
22
|
-
|
23
|
-
def remove(entity)
|
24
|
-
_remove_from_reverse_association_of(entity) if @reverse
|
25
|
-
_remove(entity)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def _add(entity)
|
31
19
|
self << entity
|
32
20
|
_store
|
33
21
|
entity
|
34
22
|
end
|
35
23
|
|
36
|
-
def
|
24
|
+
def remove(entity)
|
37
25
|
delete_if { |x| x.key == entity.key }
|
38
26
|
_store
|
39
27
|
entity
|
40
28
|
end
|
41
29
|
|
42
|
-
|
43
|
-
if entity.send(@reverse).is_a? HasMany
|
44
|
-
entity.send(@reverse).send(:_add, @this)
|
45
|
-
else
|
46
|
-
entity.send("_#{@reverse}=", @this)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def _remove_from_reverse_association_of(entity)
|
51
|
-
if entity.send(@reverse).is_a? HasMany
|
52
|
-
entity.send(@reverse).send(:_remove, @this)
|
53
|
-
else
|
54
|
-
entity.send("_#{@reverse}=", nil)
|
55
|
-
end
|
56
|
-
end
|
30
|
+
private
|
57
31
|
|
58
32
|
def _store
|
59
|
-
@this.context.hset(@key,
|
33
|
+
@this.context.hset(@key, self.map(&:key).join(' '))
|
60
34
|
end
|
61
35
|
|
62
36
|
def _fetch(clazz, context, key)
|
63
|
-
keys =
|
37
|
+
keys = (context.hget(key) || '').split.uniq
|
64
38
|
values = keys.empty? ? [] : context.hmget(*keys)
|
65
39
|
keys.zip(values).map do |key, json|
|
66
40
|
clazz.restore(context, key, json) if json
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class TestHasMany < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class Puzzle < Remodel::Entity
|
7
|
+
has_many :pieces, :class => 'TestHasMany::Piece'
|
8
|
+
property :topic
|
9
|
+
end
|
10
|
+
|
11
|
+
class Piece < Remodel::Entity
|
12
|
+
property :color
|
13
|
+
end
|
14
|
+
|
15
|
+
context "association" do
|
16
|
+
should "exist" do
|
17
|
+
assert Puzzle.create(context).respond_to?(:pieces)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "return an empty list by default" do
|
21
|
+
assert_equal [], Puzzle.create(context).pieces
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return any existing children" do
|
25
|
+
puzzle = Puzzle.create(context)
|
26
|
+
red_piece = Piece.create(context, :color => 'red')
|
27
|
+
blue_piece = Piece.create(context, :color => 'blue')
|
28
|
+
redis.hset(context.key, "#{puzzle.key}_pieces", "#{red_piece.key} #{blue_piece.key}")
|
29
|
+
assert_equal 2, puzzle.pieces.size
|
30
|
+
assert_equal Piece, puzzle.pieces[0].class
|
31
|
+
assert_equal 'red', puzzle.pieces[0].color
|
32
|
+
end
|
33
|
+
|
34
|
+
should "not return any child multiple times" do
|
35
|
+
puzzle = Puzzle.create(context)
|
36
|
+
red_piece = Piece.create(context, :color => 'red')
|
37
|
+
redis.hset(context.key, "#{puzzle.key}_pieces", "#{red_piece.key} #{red_piece.key}")
|
38
|
+
assert_equal 1, puzzle.pieces.size
|
39
|
+
assert_equal Piece, puzzle.pieces[0].class
|
40
|
+
assert_equal 'red', puzzle.pieces[0].color
|
41
|
+
end
|
42
|
+
|
43
|
+
context "create" do
|
44
|
+
should "have a create method" do
|
45
|
+
assert Puzzle.create(context).pieces.respond_to?(:create)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "work without attributes" do
|
49
|
+
puzzle = Puzzle.create(context)
|
50
|
+
piece = puzzle.pieces.create
|
51
|
+
assert piece.is_a?(Piece)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "create and store a new child" do
|
55
|
+
puzzle = Puzzle.create(context)
|
56
|
+
puzzle.pieces.create :color => 'green'
|
57
|
+
assert_equal 1, puzzle.pieces.size
|
58
|
+
puzzle.reload
|
59
|
+
assert_equal 1, puzzle.pieces.size
|
60
|
+
assert_equal Piece, puzzle.pieces[0].class
|
61
|
+
assert_equal 'green', puzzle.pieces[0].color
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "add" do
|
66
|
+
should "add the given entity to the association" do
|
67
|
+
puzzle = Puzzle.create(context)
|
68
|
+
piece = Piece.create(context, :color => 'white')
|
69
|
+
puzzle.pieces.add piece
|
70
|
+
assert_equal 1, puzzle.pieces.size
|
71
|
+
puzzle.reload
|
72
|
+
assert_equal 1, puzzle.pieces.size
|
73
|
+
assert_equal Piece, puzzle.pieces[0].class
|
74
|
+
assert_equal 'white', puzzle.pieces[0].color
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "find" do
|
79
|
+
setup do
|
80
|
+
@puzzle = Puzzle.create(context)
|
81
|
+
5.times { @puzzle.pieces.create :color => 'blue' }
|
82
|
+
end
|
83
|
+
|
84
|
+
should "find the element with the given id" do
|
85
|
+
piece = @puzzle.pieces[2]
|
86
|
+
assert_equal piece, @puzzle.pieces.find(piece.id)
|
87
|
+
end
|
88
|
+
|
89
|
+
should "raise an exception if no element with the given id exists" do
|
90
|
+
assert_raises(Remodel::EntityNotFound) { @puzzle.pieces.find(-1) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "reload" do
|
96
|
+
should "reset has_many associations" do
|
97
|
+
puzzle = Puzzle.create(context)
|
98
|
+
piece = puzzle.pieces.create :color => 'black'
|
99
|
+
redis.hdel(context.key, "#{puzzle.key}_pieces")
|
100
|
+
puzzle.reload
|
101
|
+
assert_equal [], puzzle.pieces
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
|
4
|
+
class TestHasOne < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class Piece < Remodel::Entity
|
7
|
+
has_one :puzzle, :class => 'TestHasOne::Puzzle'
|
8
|
+
property :color
|
9
|
+
end
|
10
|
+
|
11
|
+
class Puzzle < Remodel::Entity
|
12
|
+
property :topic
|
13
|
+
end
|
14
|
+
|
15
|
+
context "association getter" do
|
16
|
+
should "exist" do
|
17
|
+
assert Piece.create(context).respond_to?(:puzzle)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "return nil by default" do
|
21
|
+
assert_nil Piece.create(context).puzzle
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return the associated entity" do
|
25
|
+
puzzle = Puzzle.create(context, :topic => 'animals')
|
26
|
+
piece = Piece.create(context)
|
27
|
+
redis.hset(context.key, "#{piece.key}_puzzle", puzzle.key)
|
28
|
+
assert_equal 'animals', piece.puzzle.topic
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "association setter" do
|
33
|
+
should "exist" do
|
34
|
+
assert Piece.create(context).respond_to?(:'puzzle=')
|
35
|
+
end
|
36
|
+
|
37
|
+
should "store the key of the associated entity" do
|
38
|
+
puzzle = Puzzle.create(context)
|
39
|
+
piece = Piece.create(context)
|
40
|
+
piece.puzzle = puzzle
|
41
|
+
assert_equal puzzle.key, redis.hget(context.key, "#{piece.key}_puzzle")
|
42
|
+
end
|
43
|
+
|
44
|
+
should "be settable to nil" do
|
45
|
+
piece = Piece.create(context)
|
46
|
+
piece.puzzle = nil
|
47
|
+
assert_nil piece.puzzle
|
48
|
+
end
|
49
|
+
|
50
|
+
should "remove the key if set to nil" do
|
51
|
+
piece = Piece.create(context)
|
52
|
+
piece.puzzle = Puzzle.create(context)
|
53
|
+
piece.puzzle = nil
|
54
|
+
assert_nil redis.hget(piece.context, "#{piece.key}_puzzle")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "reload" do
|
59
|
+
should "reset has_one associations" do
|
60
|
+
piece = Piece.create(context, :color => 'black')
|
61
|
+
piece.puzzle = Puzzle.create(context)
|
62
|
+
redis.hdel(context.key, "#{piece.key}_puzzle")
|
63
|
+
piece.reload
|
64
|
+
assert_nil piece.puzzle
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestInheritance < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class Foo < Remodel::Entity
|
6
|
+
property :test
|
7
|
+
end
|
8
|
+
|
9
|
+
class Bar < Remodel::Entity
|
10
|
+
property :test
|
11
|
+
end
|
12
|
+
|
13
|
+
class Person < Remodel::Entity
|
14
|
+
property :name, :short => 'n'
|
15
|
+
has_one :foo, :class => Foo
|
16
|
+
has_many :foos, :class => Foo
|
17
|
+
end
|
18
|
+
|
19
|
+
class Admin < Person
|
20
|
+
property :password, :short => 'p'
|
21
|
+
has_one :bar, :class => Bar
|
22
|
+
has_many :bars, :class => Bar
|
23
|
+
end
|
24
|
+
|
25
|
+
context "a subclass of another entity" do
|
26
|
+
setup do
|
27
|
+
@admin = Admin.create(context, :name => 'peter', :password => 'secret')
|
28
|
+
end
|
29
|
+
|
30
|
+
should "inherit properties" do
|
31
|
+
@admin.reload
|
32
|
+
assert_equal 'peter', @admin.name
|
33
|
+
assert_equal 'secret', @admin.password
|
34
|
+
end
|
35
|
+
|
36
|
+
should "inherit has_one associations" do
|
37
|
+
@admin.foo = Foo.create(context, :test => 'foo')
|
38
|
+
@admin.bar = Bar.create(context, :test => 'bar')
|
39
|
+
@admin.reload
|
40
|
+
assert_equal 'foo', @admin.foo.test
|
41
|
+
assert_equal 'bar', @admin.bar.test
|
42
|
+
end
|
43
|
+
|
44
|
+
should "inherit has_many associations" do
|
45
|
+
@admin.foos.create(:test => 'foo')
|
46
|
+
@admin.bars.create(:test => 'bar')
|
47
|
+
@admin.reload
|
48
|
+
assert_equal 'foo', @admin.foos[0].test
|
49
|
+
assert_equal 'bar', @admin.bars[0].test
|
50
|
+
end
|
51
|
+
|
52
|
+
should "be usable as superclass" do
|
53
|
+
person = Person.find(context, @admin.key)
|
54
|
+
assert_equal 'peter', person.name
|
55
|
+
assert_raise(NoMethodError) { person.password }
|
56
|
+
end
|
57
|
+
|
58
|
+
should "use property shortnames in redis" do
|
59
|
+
json = redis.hget(context.key, @admin.key)
|
60
|
+
assert_match /"n":/, json
|
61
|
+
assert_match /"p":/, json
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestShortnames < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class Foo < Remodel::Entity; end
|
6
|
+
|
7
|
+
class Bar < Remodel::Entity
|
8
|
+
property :test, :short => 'z'
|
9
|
+
has_one :foo, :short => 'y', :class => Foo
|
10
|
+
has_many :foos, :short => 'x', :class => Foo
|
11
|
+
end
|
12
|
+
|
13
|
+
context "property shortnames" do
|
14
|
+
setup do
|
15
|
+
@bar = Bar.create(context, :test => 42)
|
16
|
+
end
|
17
|
+
|
18
|
+
should "be used when storing properties" do
|
19
|
+
serialized = redis.hget(context.key, @bar.key)
|
20
|
+
assert !serialized.match(/test/)
|
21
|
+
assert serialized.match(/z/)
|
22
|
+
end
|
23
|
+
|
24
|
+
should "work in roundtrip" do
|
25
|
+
@bar.reload
|
26
|
+
assert_equal 42, @bar.test
|
27
|
+
end
|
28
|
+
|
29
|
+
should "not be used in as_json" do
|
30
|
+
assert !@bar.as_json.has_key?(:z)
|
31
|
+
assert @bar.as_json.has_key?(:test)
|
32
|
+
end
|
33
|
+
|
34
|
+
should "not be used in inspect" do
|
35
|
+
assert !@bar.inspect.match(/z/)
|
36
|
+
assert @bar.inspect.match(/test/)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "has_one shortnames" do
|
41
|
+
setup do
|
42
|
+
@bar = Bar.create(context, :test => 42)
|
43
|
+
@bar.foo = Foo.create(context)
|
44
|
+
end
|
45
|
+
|
46
|
+
should "be used when storing" do
|
47
|
+
assert_not_nil redis.hget(context.key, "#{@bar.key}_y")
|
48
|
+
end
|
49
|
+
|
50
|
+
should "work in roundtrip" do
|
51
|
+
@bar.reload
|
52
|
+
assert_not_nil @bar.foo
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "has_many shortnames" do
|
57
|
+
setup do
|
58
|
+
@bar = Bar.create(context, :test => 42)
|
59
|
+
@bar.foos.create
|
60
|
+
@bar.foos.create
|
61
|
+
end
|
62
|
+
|
63
|
+
should "be used when storing" do
|
64
|
+
assert_not_nil redis.hget(context.key, "#{@bar.key}_x")
|
65
|
+
end
|
66
|
+
|
67
|
+
should "work in roundtrip" do
|
68
|
+
@bar.reload
|
69
|
+
assert_equal 2, @bar.foos.size
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 5
|
8
|
+
- 0
|
9
|
+
version: 0.5.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Tim Lossen
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-08-
|
17
|
+
date: 2011-08-16 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -32,8 +32,6 @@ files:
|
|
32
32
|
- README.md
|
33
33
|
- Rakefile
|
34
34
|
- VERSION
|
35
|
-
- docs/docco.css
|
36
|
-
- docs/remodel.html
|
37
35
|
- example/book.rb
|
38
36
|
- lib/remodel.rb
|
39
37
|
- lib/remodel/caching_context.rb
|
@@ -46,14 +44,13 @@ files:
|
|
46
44
|
- test/test_entity.rb
|
47
45
|
- test/test_entity_defaults.rb
|
48
46
|
- test/test_entity_delete.rb
|
49
|
-
- test/
|
50
|
-
- test/
|
51
|
-
- test/
|
47
|
+
- test/test_has_many.rb
|
48
|
+
- test/test_has_one.rb
|
49
|
+
- test/test_inheritance.rb
|
52
50
|
- test/test_mappers.rb
|
53
51
|
- test/test_monkeypatches.rb
|
54
|
-
- test/test_one_to_many.rb
|
55
|
-
- test/test_one_to_one.rb
|
56
52
|
- test/test_remodel.rb
|
53
|
+
- test/test_shortnames.rb
|
57
54
|
has_rdoc: true
|
58
55
|
homepage: http://github.com/tlossen/remodel
|
59
56
|
licenses: []
|
@@ -92,11 +89,10 @@ test_files:
|
|
92
89
|
- test/test_entity.rb
|
93
90
|
- test/test_entity_defaults.rb
|
94
91
|
- test/test_entity_delete.rb
|
95
|
-
- test/
|
96
|
-
- test/
|
97
|
-
- test/
|
92
|
+
- test/test_has_many.rb
|
93
|
+
- test/test_has_one.rb
|
94
|
+
- test/test_inheritance.rb
|
98
95
|
- test/test_mappers.rb
|
99
96
|
- test/test_monkeypatches.rb
|
100
|
-
- test/test_one_to_many.rb
|
101
|
-
- test/test_one_to_one.rb
|
102
97
|
- test/test_remodel.rb
|
98
|
+
- test/test_shortnames.rb
|