redis_orm 0.1 → 0.2
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 +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
|