redis_orm 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/Manifest +2 -0
- data/README.md +55 -4
- data/Rakefile +1 -1
- data/lib/redis_orm.rb +2 -0
- data/lib/redis_orm/associations/belongs_to.rb +29 -7
- data/lib/redis_orm/associations/has_many.rb +1 -1
- data/lib/redis_orm/associations/has_one.rb +2 -4
- data/lib/redis_orm/redis_orm.rb +19 -12
- data/redis_orm.gemspec +5 -5
- data/test/associations_test.rb +25 -1
- data/test/basic_functionality_test.rb +14 -0
- data/test/options_test.rb +3 -3
- data/test/polymorphic_test.rb +109 -0
- metadata +14 -10
data/CHANGELOG
ADDED
data/Manifest
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
RedisOrm supposed to be *almost* drop-in replacement of ActiveRecord. It's based on the [Redis](http://redis.io) advanced key-value store and is work in progress.
|
1
|
+
RedisOrm supposed to be *almost* drop-in replacement of ActiveRecord 2.x. It's based on the [Redis](http://redis.io) - advanced key-value store and is work in progress.
|
2
2
|
|
3
3
|
Here's the standard model definition:
|
4
4
|
|
@@ -6,8 +6,12 @@ Here's the standard model definition:
|
|
6
6
|
class User < RedisOrm::Base
|
7
7
|
property :first_name, String
|
8
8
|
property :last_name, String
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
timestamps
|
11
|
+
|
12
|
+
# OR
|
13
|
+
# property :created_at, Time
|
14
|
+
# property :modified_at, Time
|
11
15
|
|
12
16
|
index :last_name
|
13
17
|
index [:first_name, :last_name]
|
@@ -246,7 +250,52 @@ friend2.friends # => []
|
|
246
250
|
|
247
251
|
As an exception if *:as* option for the association is provided the backlinks are not established.
|
248
252
|
|
249
|
-
|
253
|
+
### Polymorphic associations
|
254
|
+
|
255
|
+
Polymorphic associations work the same way they do in ActiveRecord (2 keys are created to store type and id of the record)
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
class CatalogItem < RedisOrm::Base
|
259
|
+
property :title, String
|
260
|
+
|
261
|
+
belongs_to :resource, :polymorphic => true
|
262
|
+
end
|
263
|
+
|
264
|
+
class Book < RedisOrm::Base
|
265
|
+
property :price, Integer
|
266
|
+
property :title, String
|
267
|
+
|
268
|
+
has_one :catalog_item
|
269
|
+
end
|
270
|
+
|
271
|
+
class Giftcard < RedisOrm::Base
|
272
|
+
property :price, Integer
|
273
|
+
property :title, String
|
274
|
+
|
275
|
+
has_one :catalog_item
|
276
|
+
end
|
277
|
+
|
278
|
+
book = Book.create :title => "Permutation City", :author => "Egan Greg", :price => 1529
|
279
|
+
giftcard = Giftcard.create :title => "Happy New Year!"
|
280
|
+
|
281
|
+
ci1 = CatalogItem.create :title => giftcard.title
|
282
|
+
ci1.resource = giftcard
|
283
|
+
|
284
|
+
ci2 = CatalogItem.create :title => book.title
|
285
|
+
ci2.resource = book
|
286
|
+
```
|
287
|
+
|
288
|
+
All associations supports following options:
|
289
|
+
|
290
|
+
* *:as*
|
291
|
+
|
292
|
+
Symbol could be accessed by provided name
|
293
|
+
|
294
|
+
* *:dependent*
|
295
|
+
|
296
|
+
Symbol could be either :destroy or :nullify (default value)
|
297
|
+
|
298
|
+
For more examples please check test/associations_test.rb and test/polymorphic_test.rb
|
250
299
|
|
251
300
|
## Validation
|
252
301
|
|
@@ -329,4 +378,6 @@ describe "check callbacks" do
|
|
329
378
|
end
|
330
379
|
```
|
331
380
|
|
381
|
+
To run all tests just invoke *rake test*
|
382
|
+
|
332
383
|
Copyright © 2011 Dmitrii Samoilov, released under the MIT license
|
data/Rakefile
CHANGED
data/lib/redis_orm.rb
CHANGED
@@ -21,25 +21,47 @@ module RedisOrm
|
|
21
21
|
end
|
22
22
|
|
23
23
|
define_method foreign_model_name.to_sym do
|
24
|
-
|
24
|
+
if options[:polymorphic]
|
25
|
+
model_type = $redis.get("#{model_name}:#{id}:#{foreign_model_name}_type")
|
26
|
+
if model_type
|
27
|
+
model_type.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}_id")
|
28
|
+
end
|
29
|
+
else
|
30
|
+
foreign_model.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
|
31
|
+
end
|
25
32
|
end
|
26
33
|
|
27
34
|
# look = Look.create :title => 'test'
|
28
35
|
# look.user = User.find(1) => look:23:user => 1
|
29
36
|
define_method "#{foreign_model_name}=" do |assoc_with_record|
|
30
|
-
|
31
|
-
|
37
|
+
old_assoc = nil
|
38
|
+
|
39
|
+
if options[:polymorphic]
|
40
|
+
# we need to store this to clear old association later
|
41
|
+
old_assoc = self.send(foreign_model_name)
|
42
|
+
$redis.set("#{model_name}:#{id}:#{foreign_model_name}_type", assoc_with_record.model_name)
|
43
|
+
$redis.set("#{model_name}:#{id}:#{foreign_model_name}_id", assoc_with_record.id)
|
32
44
|
else
|
33
|
-
|
45
|
+
if assoc_with_record.model_name == foreign_model.to_s
|
46
|
+
$redis.set("#{model_name}:#{id}:#{foreign_model_name}", assoc_with_record.id)
|
47
|
+
else
|
48
|
+
raise TypeMismatchError
|
49
|
+
end
|
34
50
|
end
|
35
|
-
|
51
|
+
|
36
52
|
# check whether *assoc_with_record* object has *has_many* declaration and TODO it states *self.model_name* in plural and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
|
37
|
-
if class_associations[assoc_with_record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
|
53
|
+
if class_associations[assoc_with_record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
|
54
|
+
# remove old assoc
|
55
|
+
if old_assoc
|
56
|
+
$redis.zrem "#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id
|
57
|
+
end
|
58
|
+
|
38
59
|
assoc_with_record.send(model_name.pluralize.to_sym).send(:"<<", self)
|
39
60
|
|
40
61
|
# check whether *assoc_with_record* object has *has_one* declaration and TODO it states *self.model_name* and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
|
41
62
|
elsif class_associations[assoc_with_record.model_name].detect{|h| h[:type] == :has_one && h[:foreign_model] == model_name.to_sym} && assoc_with_record.send(model_name.to_sym).nil?
|
42
|
-
|
63
|
+
# old association is being rewritten here automatically so we don't have to worry about it
|
64
|
+
assoc_with_record.send("#{model_name}=", self)
|
43
65
|
end
|
44
66
|
end
|
45
67
|
end
|
@@ -28,7 +28,7 @@ module RedisOrm
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# clear old assocs from this model side
|
31
|
-
$redis.zremrangebyscore "#{model_name}:#{id}:#{
|
31
|
+
$redis.zremrangebyscore "#{model_name}:#{id}:#{foreign_models}", 0, Time.now.to_f
|
32
32
|
end
|
33
33
|
|
34
34
|
records.to_a.each do |record|
|
@@ -33,13 +33,11 @@ module RedisOrm
|
|
33
33
|
|
34
34
|
# check whether *assoc_with_record* object has *belongs_to* declaration and TODO it states *self.model_name* and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
|
35
35
|
if class_associations[assoc_with_record.model_name].detect{|h| [:belongs_to, :has_one].include?(h[:type]) && h[:foreign_model] == model_name.to_sym} && assoc_with_record.send(model_name.to_sym).nil?
|
36
|
+
# old association is being rewritten here automatically so we don't have to worry about it
|
36
37
|
assoc_with_record.send("#{model_name}=", self)
|
37
38
|
elsif class_associations[assoc_with_record.model_name].detect{|h| :has_many == h[:type] && h[:foreign_models] == model_name.to_s.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
|
38
|
-
# remove old assoc
|
39
|
-
# $redis.zrank "city:2:profiles", 12
|
39
|
+
# remove old assoc
|
40
40
|
if old_assoc
|
41
|
-
#puts 'key - ' + "#{assoc_with_record.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}"
|
42
|
-
#puts 'self.id - ' + self.id.to_s
|
43
41
|
$redis.zrem "#{assoc_with_record.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id
|
44
42
|
end
|
45
43
|
# create/add new ones
|
data/lib/redis_orm/redis_orm.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
1
3
|
require 'active_support/inflector/inflections'
|
2
4
|
require 'active_support/inflector/transliterate'
|
3
5
|
require 'active_support/inflector/methods'
|
@@ -78,7 +80,7 @@ module RedisOrm
|
|
78
80
|
value
|
79
81
|
end
|
80
82
|
|
81
|
-
send(:define_method,
|
83
|
+
send(:define_method, "#{property_name}=".to_sym) do |value|
|
82
84
|
if instance_variable_get(:"@#{property_name}_changes") && !instance_variable_get(:"@#{property_name}_changes").empty?
|
83
85
|
initial_value = instance_variable_get(:"@#{property_name}_changes")[0]
|
84
86
|
instance_variable_set(:"@#{property_name}_changes", [initial_value, value])
|
@@ -91,11 +93,23 @@ module RedisOrm
|
|
91
93
|
instance_variable_set(:"@#{property_name}", value)
|
92
94
|
end
|
93
95
|
|
94
|
-
send(:define_method,
|
96
|
+
send(:define_method, "#{property_name}_changes".to_sym) do
|
95
97
|
instance_variable_get(:"@#{property_name}_changes")
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
101
|
+
def timestamps
|
102
|
+
#if !@@properties[model_name].detect{|p| p[:name] == :created_at && p[:class] == "Time"}
|
103
|
+
if !instance_methods.include?(:created_at) && !instance_methods.include?(:"created_at=")
|
104
|
+
property :created_at, Time
|
105
|
+
end
|
106
|
+
|
107
|
+
#if !@@properties[model_name].detect{|p| p[:name] == :modified_at && p[:class] == "Time"}
|
108
|
+
if !instance_methods.include?(:modified_at) && !instance_methods.include?(:"modified_at=")
|
109
|
+
property :modified_at, Time
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
99
113
|
def count
|
100
114
|
$redis.zcard("#{model_name}:ids").to_i
|
101
115
|
end
|
@@ -325,9 +339,7 @@ module RedisOrm
|
|
325
339
|
$redis.zadd "#{model_name}:ids", Time.now.to_f, @id
|
326
340
|
@persisted = true
|
327
341
|
|
328
|
-
|
329
|
-
self.created_at = Time.now
|
330
|
-
end
|
342
|
+
self.created_at = Time.now if respond_to? :created_at
|
331
343
|
end
|
332
344
|
|
333
345
|
@@callbacks[model_name][:before_save].each do |callback|
|
@@ -335,9 +347,7 @@ module RedisOrm
|
|
335
347
|
end
|
336
348
|
|
337
349
|
# automatically update *modified_at* property if it was defined
|
338
|
-
|
339
|
-
self.modified_at = Time.now
|
340
|
-
end
|
350
|
+
self.modified_at = Time.now if respond_to? :modified_at
|
341
351
|
|
342
352
|
@@properties[model_name].each do |prop|
|
343
353
|
prop_value = self.send(prop[:name].to_sym)
|
@@ -451,23 +461,20 @@ module RedisOrm
|
|
451
461
|
# for if class Album; has_one :photo, :as => :front_photo; has_many :photos; end
|
452
462
|
# end some photo from the album will be deleted w/o these checks only first has_one will be triggered
|
453
463
|
if @@associations[foreign_model].detect{|h| h[:type] == :belongs_to && h[:foreign_model] == model_name.to_sym}
|
454
|
-
#puts 'from destr :belongs_to - ' + "#{foreign_model}:#{record.id}:#{model_name}"
|
455
464
|
$redis.del "#{foreign_model}:#{record.id}:#{model_name}"
|
456
465
|
end
|
457
466
|
|
458
467
|
if @@associations[foreign_model].detect{|h| h[:type] == :has_one && h[:foreign_model] == model_name.to_sym}
|
459
|
-
#puts 'from destr :has_one - ' + "#{foreign_model}:#{record.id}:#{model_name}"
|
460
468
|
$redis.del "#{foreign_model}:#{record.id}:#{model_name}"
|
461
469
|
end
|
462
470
|
|
463
471
|
if @@associations[foreign_model].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym}
|
464
|
-
#puts "from destr :has_many - " + "#{foreign_model}:#{record.id}:#{model_name.pluralize}"
|
465
472
|
$redis.zrem "#{foreign_model}:#{record.id}:#{model_name.pluralize}", @id
|
466
473
|
end
|
467
474
|
end
|
468
475
|
end
|
469
476
|
|
470
|
-
if assoc[:options][:
|
477
|
+
if assoc[:options][:dependent] == :destroy
|
471
478
|
records.each do |r|
|
472
479
|
r.destroy
|
473
480
|
end
|
data/redis_orm.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{redis_orm}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Dmitrii Samoilov"]
|
9
|
-
s.date = %q{2011-06-
|
9
|
+
s.date = %q{2011-06-04}
|
10
10
|
s.description = %q{ORM for Redis advanced key-value storage}
|
11
11
|
s.email = %q{germaninthetown@gmail.com}
|
12
|
-
s.extra_rdoc_files = ["LICENSE", "README.md", "lib/redis_orm.rb", "lib/redis_orm/active_model_behavior.rb", "lib/redis_orm/associations/belongs_to.rb", "lib/redis_orm/associations/has_many.rb", "lib/redis_orm/associations/has_many_proxy.rb", "lib/redis_orm/associations/has_one.rb", "lib/redis_orm/redis_orm.rb"]
|
13
|
-
s.files = ["LICENSE", "Manifest", "README.md", "Rakefile", "lib/redis_orm.rb", "lib/redis_orm/active_model_behavior.rb", "lib/redis_orm/associations/belongs_to.rb", "lib/redis_orm/associations/has_many.rb", "lib/redis_orm/associations/has_many_proxy.rb", "lib/redis_orm/associations/has_one.rb", "lib/redis_orm/redis_orm.rb", "redis_orm.gemspec", "test/associations_test.rb", "test/basic_functionality_test.rb", "test/callbacks_test.rb", "test/changes_array_test.rb", "test/dynamic_finders_test.rb", "test/exceptions_test.rb", "test/has_one_has_many_test.rb", "test/indices_test.rb", "test/options_test.rb", "test/redis.conf", "test/validations_test.rb"]
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/redis_orm.rb", "lib/redis_orm/active_model_behavior.rb", "lib/redis_orm/associations/belongs_to.rb", "lib/redis_orm/associations/has_many.rb", "lib/redis_orm/associations/has_many_proxy.rb", "lib/redis_orm/associations/has_one.rb", "lib/redis_orm/redis_orm.rb"]
|
13
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.md", "Rakefile", "lib/redis_orm.rb", "lib/redis_orm/active_model_behavior.rb", "lib/redis_orm/associations/belongs_to.rb", "lib/redis_orm/associations/has_many.rb", "lib/redis_orm/associations/has_many_proxy.rb", "lib/redis_orm/associations/has_one.rb", "lib/redis_orm/redis_orm.rb", "redis_orm.gemspec", "test/associations_test.rb", "test/basic_functionality_test.rb", "test/callbacks_test.rb", "test/changes_array_test.rb", "test/dynamic_finders_test.rb", "test/exceptions_test.rb", "test/has_one_has_many_test.rb", "test/indices_test.rb", "test/options_test.rb", "test/polymorphic_test.rb", "test/redis.conf", "test/validations_test.rb"]
|
14
14
|
s.homepage = %q{https://github.com/german/redis_orm}
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Redis_orm", "--main", "README.md"]
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = %q{redis_orm}
|
18
18
|
s.rubygems_version = %q{1.6.2}
|
19
19
|
s.summary = %q{ORM for Redis advanced key-value storage}
|
20
|
-
s.test_files = ["test/options_test.rb", "test/dynamic_finders_test.rb", "test/associations_test.rb", "test/validations_test.rb", "test/exceptions_test.rb", "test/has_one_has_many_test.rb", "test/indices_test.rb", "test/changes_array_test.rb", "test/callbacks_test.rb", "test/basic_functionality_test.rb"]
|
20
|
+
s.test_files = ["test/options_test.rb", "test/dynamic_finders_test.rb", "test/associations_test.rb", "test/validations_test.rb", "test/polymorphic_test.rb", "test/exceptions_test.rb", "test/has_one_has_many_test.rb", "test/indices_test.rb", "test/changes_array_test.rb", "test/callbacks_test.rb", "test/basic_functionality_test.rb"]
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
23
23
|
s.specification_version = 3
|
data/test/associations_test.rb
CHANGED
@@ -72,11 +72,35 @@ describe "check associations" do
|
|
72
72
|
Process.kill 9, $redis_pid.to_i if $redis_pid
|
73
73
|
end
|
74
74
|
|
75
|
+
it "should assign properly from belongs_to side" do
|
76
|
+
@comment1.article.should == nil
|
77
|
+
@comment1.article = @article
|
78
|
+
@comment1.article.id.should == @article.id
|
79
|
+
@article.comments.count.should == 1
|
80
|
+
@article.comments[0].id.should == @comment1.id
|
81
|
+
|
82
|
+
@comment2.article.should == nil
|
83
|
+
@comment2.article = @article
|
84
|
+
@comment2.article.id.should == @article.id
|
85
|
+
@article.comments.count.should == 2
|
86
|
+
@article.comments[0].id.should == @comment2.id
|
87
|
+
|
88
|
+
#@comment1.article = nil
|
89
|
+
#@article.comments.count.should == 1
|
90
|
+
#@comment1.article.should == nil
|
91
|
+
end
|
92
|
+
|
75
93
|
it "should return array" do
|
94
|
+
@article.comments << []
|
95
|
+
@article.comments.count.should == 0
|
96
|
+
|
97
|
+
@article.comments = []
|
98
|
+
@article.comments.count.should == 0
|
99
|
+
|
76
100
|
@article.comments << [@comment1, @comment2]
|
77
101
|
#@article.comments.should be_kind_of(Array)
|
78
102
|
|
79
|
-
@article.comments.count.should == 2
|
103
|
+
@article.comments.count.should == 2
|
80
104
|
@article.comments.size.should == 2
|
81
105
|
|
82
106
|
@comment1.article.should be
|
@@ -21,6 +21,10 @@ class DefaultUser < RedisOrm::Base
|
|
21
21
|
property :modified_at, Time
|
22
22
|
end
|
23
23
|
|
24
|
+
class TimeStamp < RedisOrm::Base
|
25
|
+
timestamps
|
26
|
+
end
|
27
|
+
|
24
28
|
describe "check basic functionality" do
|
25
29
|
before(:all) do
|
26
30
|
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
@@ -163,4 +167,14 @@ describe "check basic functionality" do
|
|
163
167
|
u.age.should == 26
|
164
168
|
u.wage.should == 256.25
|
165
169
|
end
|
170
|
+
|
171
|
+
it "should expand timestamps declaration properly" do
|
172
|
+
t = TimeStamp.new
|
173
|
+
t.save
|
174
|
+
|
175
|
+
t.created_at.should be
|
176
|
+
t.modified_at.should be
|
177
|
+
t.created_at.day.should == Time.now.day
|
178
|
+
t.modified_at.day.should == Time.now.day
|
179
|
+
end
|
166
180
|
end
|
data/test/options_test.rb
CHANGED
@@ -5,13 +5,13 @@ class Album < RedisOrm::Base
|
|
5
5
|
property :title, String
|
6
6
|
|
7
7
|
has_one :photo, :as => :front_photo
|
8
|
-
has_many :photos, :
|
8
|
+
has_many :photos, :dependent => :destroy
|
9
9
|
end
|
10
10
|
|
11
11
|
class Category < RedisOrm::Base
|
12
12
|
property :title, String
|
13
13
|
|
14
|
-
has_many :photos, :
|
14
|
+
has_many :photos, :dependent => :nullify
|
15
15
|
end
|
16
16
|
|
17
17
|
class Photo < RedisOrm::Base
|
@@ -25,7 +25,7 @@ end
|
|
25
25
|
class User < RedisOrm::Base
|
26
26
|
property :name, String
|
27
27
|
|
28
|
-
has_one :photo, :
|
28
|
+
has_one :photo, :dependent => :destroy
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "test options" do
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
3
|
+
|
4
|
+
class CatalogItem < RedisOrm::Base
|
5
|
+
property :title, String
|
6
|
+
|
7
|
+
belongs_to :resource, :polymorphic => true
|
8
|
+
end
|
9
|
+
|
10
|
+
class Book < RedisOrm::Base
|
11
|
+
property :price, Integer, :default => 0 # in cents
|
12
|
+
property :title, String
|
13
|
+
|
14
|
+
has_one :catalog_item
|
15
|
+
end
|
16
|
+
|
17
|
+
class Giftcard < RedisOrm::Base
|
18
|
+
property :price, Integer, :default => 0 # in cents
|
19
|
+
property :title, String
|
20
|
+
|
21
|
+
has_one :catalog_item
|
22
|
+
end
|
23
|
+
|
24
|
+
# for second test
|
25
|
+
class Person < RedisOrm::Base
|
26
|
+
property :name, String
|
27
|
+
|
28
|
+
belongs_to :location, :polymorphic => true
|
29
|
+
end
|
30
|
+
|
31
|
+
class Country < RedisOrm::Base
|
32
|
+
property :name, String
|
33
|
+
|
34
|
+
has_many :people
|
35
|
+
end
|
36
|
+
|
37
|
+
class City < RedisOrm::Base
|
38
|
+
property :name, String
|
39
|
+
|
40
|
+
has_many :people
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "check polymorphic property" do
|
44
|
+
before(:all) do
|
45
|
+
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
46
|
+
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
47
|
+
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
48
|
+
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
49
|
+
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
50
|
+
end
|
51
|
+
|
52
|
+
before(:each) do
|
53
|
+
$redis.flushall if $redis
|
54
|
+
end
|
55
|
+
|
56
|
+
after(:each) do
|
57
|
+
$redis.flushall if $redis
|
58
|
+
end
|
59
|
+
|
60
|
+
after(:all) do
|
61
|
+
Process.kill 9, $redis_pid.to_i if $redis_pid
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should provide proper associations and save records correctly for has_one/belongs_to polymorphic" do
|
65
|
+
book = Book.new :title => "Permutation City", :author => "Egan Greg", :price => 1529
|
66
|
+
book.save
|
67
|
+
|
68
|
+
giftcard = Giftcard.create :title => "Happy New Year!"
|
69
|
+
|
70
|
+
ci1 = CatalogItem.create :title => giftcard.title
|
71
|
+
ci1.resource = giftcard
|
72
|
+
|
73
|
+
ci2 = CatalogItem.create :title => book.title
|
74
|
+
ci2.resource = book
|
75
|
+
|
76
|
+
CatalogItem.count.should == 2
|
77
|
+
[ci1, ci2].collect{|ci| ci.title}.should == [giftcard.title, book.title]
|
78
|
+
|
79
|
+
ci1.resource.title.should == giftcard.title
|
80
|
+
ci2.resource.title.should == book.title
|
81
|
+
|
82
|
+
Book.first.catalog_item.should be
|
83
|
+
Book.first.catalog_item.id.should == ci2.id
|
84
|
+
|
85
|
+
Giftcard.first.catalog_item.should be
|
86
|
+
Giftcard.first.catalog_item.id.should == ci1.id
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should provide proper associations and save records correctly for has_many/belongs_to polymorphic" do
|
90
|
+
country = Country.create :name => "Ukraine"
|
91
|
+
city = City.create :name => "Lviv"
|
92
|
+
|
93
|
+
person = Person.create :name => "german"
|
94
|
+
person.location = country
|
95
|
+
|
96
|
+
Person.first.location.id.should == country.id
|
97
|
+
City.first.people.count.should == 0
|
98
|
+
Country.first.people.count.should == 1
|
99
|
+
Country.first.people[0].id.should == person.id
|
100
|
+
|
101
|
+
person = Person.first
|
102
|
+
person.location = city
|
103
|
+
|
104
|
+
Person.first.location.id.should == city.id
|
105
|
+
City.first.people.count.should == 1
|
106
|
+
City.first.people[0].id.should == person.id
|
107
|
+
Country.first.people.count.should == 0
|
108
|
+
end
|
109
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_orm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-06-
|
12
|
+
date: 2011-06-04 00:00:00.000000000 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
17
|
-
requirement: &
|
17
|
+
requirement: &85876430 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 3.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *85876430
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: activemodel
|
28
|
-
requirement: &
|
28
|
+
requirement: &85876070 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 3.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *85876070
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: redis
|
39
|
-
requirement: &
|
39
|
+
requirement: &85875730 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 2.2.0
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *85875730
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rspec
|
50
|
-
requirement: &
|
50
|
+
requirement: &85875400 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,12 +55,13 @@ dependencies:
|
|
55
55
|
version: 2.5.0
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *85875400
|
59
59
|
description: ORM for Redis advanced key-value storage
|
60
60
|
email: germaninthetown@gmail.com
|
61
61
|
executables: []
|
62
62
|
extensions: []
|
63
63
|
extra_rdoc_files:
|
64
|
+
- CHANGELOG
|
64
65
|
- LICENSE
|
65
66
|
- README.md
|
66
67
|
- lib/redis_orm.rb
|
@@ -71,6 +72,7 @@ extra_rdoc_files:
|
|
71
72
|
- lib/redis_orm/associations/has_one.rb
|
72
73
|
- lib/redis_orm/redis_orm.rb
|
73
74
|
files:
|
75
|
+
- CHANGELOG
|
74
76
|
- LICENSE
|
75
77
|
- Manifest
|
76
78
|
- README.md
|
@@ -92,6 +94,7 @@ files:
|
|
92
94
|
- test/has_one_has_many_test.rb
|
93
95
|
- test/indices_test.rb
|
94
96
|
- test/options_test.rb
|
97
|
+
- test/polymorphic_test.rb
|
95
98
|
- test/redis.conf
|
96
99
|
- test/validations_test.rb
|
97
100
|
has_rdoc: true
|
@@ -130,6 +133,7 @@ test_files:
|
|
130
133
|
- test/dynamic_finders_test.rb
|
131
134
|
- test/associations_test.rb
|
132
135
|
- test/validations_test.rb
|
136
|
+
- test/polymorphic_test.rb
|
133
137
|
- test/exceptions_test.rb
|
134
138
|
- test/has_one_has_many_test.rb
|
135
139
|
- test/indices_test.rb
|