remodel 0.4.2 → 0.5.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/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
|