redis_orm 0.5.1 → 0.8

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2ca054af9087bbd76a32022f1fee369a5ef0292c15e1b091fddbab2aadb2649f
4
+ data.tar.gz: 142417a34ecdd550195ec800aff8157d24c5cde06601e69a99c2916d23577e5c
5
+ SHA512:
6
+ metadata.gz: 7855dfe1ea7f968d17546eb9ff1ade0d9a50b7548f1a297a31cd1ecd1d60329c89dcefedf6affbc107634425b4f0a3828b6b573a5fa46d807c4167e0cea9dbc3
7
+ data.tar.gz: 2313d1c202ca558573468a93ec4d47beb278069b454e245aaeb65280ce8bc891ac1e89e03df85980c303787ea1e15f4f4220ba61d2f515823b05dcb1a8e939a6
data/CHANGELOG CHANGED
@@ -1,3 +1,32 @@
1
+ v0.7 [03-05-2013]
2
+ FEATURES
3
+ * implemented Array and Hash properties types
4
+ * added ability to specify an *expire* value for the record via method of the class and added inline *expire_in* key that can be used while saving objects (referencial keys in expireable record also expireables)
5
+ * Add model generator [Tatsuya Sato]
6
+ BUGS
7
+ * fixed a bug with Date property implementation
8
+ * refactored *save* method
9
+
10
+ v0.6.2 [23-05-2012]
11
+ * adds an ability to specify/create indices on *has_one* and *belongs_to* associations
12
+ * fixed error with updating indices in *belongs_to* association with :as option
13
+ * tests refactoring, now all tests are run with Rake::TestTask
14
+ * moved all classes and modules from test cases to special folders (test/classes, test/modules)
15
+ * fixed bug: :default values should be properly transformed to the right classes (if :default values are wrong) so when comparing them to other/stored instances they'll be the same
16
+
17
+ v0.6.1 [05-12-2011]
18
+ * rewritten sortable functionality for attributes which values are strings
19
+ * added Gemfile to the project, improved tests
20
+
21
+ v0.6 [12-09-2011]
22
+ * added equality operator for object, #to_s method for inspecting objects, #find! which could throw RecordNotFound error
23
+ * added self.descendants class method which returns all inherited from RedisOrm::Base classes
24
+ * introduced :sortable option (in property declaration and #find conditions hash) - rudimentary ability to sort records by any property (not just by default 'created_at')
25
+ * now handling models withing modules definitions (test for this in associations_test.rb)
26
+ * properly handling :as parameter in options for has_many/belongs_to self-references
27
+ * binding related models while creating model instance (like this: Article.create(:comment => comment))
28
+ * bunch of small fixes, updated tests and README.md
29
+
1
30
  v0.5.1 [27-07-2011]
2
31
  * added support of uuid as an id/primary key
3
32
  * added documentation on uuid support and connection to the redis server
data/README.md CHANGED
@@ -27,6 +27,28 @@ class User < RedisOrm::Base
27
27
  end
28
28
  ```
29
29
 
30
+ ## Installing redis_orm
31
+
32
+ stable release:
33
+
34
+ ```sh
35
+ gem install redis_orm
36
+ ```
37
+
38
+ or edge version:
39
+
40
+ ```sh
41
+ git clone git://github.com/german/redis_orm.git
42
+ cd redis_orm
43
+ bundle install
44
+ ```
45
+
46
+ To run the tests you should have redis installed already. Please check [Redis download/installation page](http://redis.io/download).
47
+
48
+ ```sh
49
+ rspec
50
+ ```
51
+
30
52
  ## Setting up a connection to the redis server
31
53
 
32
54
  If you are using Rails you should initialize redis and set up global $redis variable in *config/initializers/redis.rb* file:
@@ -60,14 +82,48 @@ Supported property types:
60
82
  * **RedisOrm::Boolean**
61
83
  there is no Boolean class in Ruby so it's a special class to store TrueClass or FalseClass objects
62
84
 
63
- * **Time**
85
+ * **Time** or **DateTime**
64
86
 
87
+ * **Array** or **Hash**
88
+ RedisOrm automatically will handle serializing/deserializing arrays and hashes into strings using Marshal class
89
+
65
90
  Following options are available in property declaration:
66
91
 
67
92
  * **:default**
68
93
 
69
94
  The default value of the attribute when it's getting saved w/o any.
70
95
 
96
+ * **:sortable**
97
+
98
+ if *true* is specified then you could sort records by this property later
99
+
100
+ *Note* that when you're using :sortable option redis_orm maintains one additional list per attribute. Also note that the #create method could be 3 times slower in some cases (this will be improved in future releases), while the #find performance is basically the same (see the "benchmarks/sortable_benchmark.rb").
101
+
102
+ ## Expiring record after certain period of time
103
+
104
+ You could expire record stored in Redis by specifying TTL in seconds invoking *expire* method of the class like this:
105
+
106
+ ```ruby
107
+ class PhantomUser < RedisOrm::Base
108
+ property :name, String
109
+ property :persist, RedisOrm::Boolean, :default => true
110
+
111
+ expire 15.minutes.from_now
112
+ end
113
+ ```
114
+
115
+ Also you could specify a condition when *expire* would be set on record's key:
116
+
117
+ ```ruby
118
+ expire 15.minutes.from_now, :if => Proc.new {|r| !r.persist?}
119
+ ```
120
+
121
+ Also you could override class method *expire* by using *expire_in* key when saving object:
122
+
123
+ ```ruby
124
+ ExpireUser.create :name => "Ghost record", :expire_in => 50.minutes.from_now
125
+ ```
126
+
71
127
  ## Searching records by the value
72
128
 
73
129
  Usually it's done via declaring an index and using *:conditions* hash or dynamic finders. For example:
@@ -102,7 +158,11 @@ To extract all or part of the associated records you could use 4 options:
102
158
 
103
159
  * :order
104
160
 
105
- Either :desc or :asc (default), since records are stored with *Time.now.to_f* scores, by default they could be fetched only in that (or reversed) order. To store them in different order you should *zadd* record's id to some other sorted list manually.
161
+ Either :desc or :asc (default), since records are stored with *Time.now.to_f* scores, by default they could be fetched only in that (or reversed) order. To order by different property you should:
162
+
163
+ 1. specify *:sortable => true* as option in property declaration
164
+
165
+ 2. specify the property by which you wish to order *:order => [:name, :desc]* or *:order => [:name]* (:asc order is default)
106
166
 
107
167
  * :conditions
108
168
 
@@ -508,6 +568,10 @@ end
508
568
 
509
569
  To run all tests just invoke *rake test*
510
570
 
571
+ ## Contributors
572
+
573
+ [Tatsuya Sato](https://github.com/satoryu)
574
+
511
575
  Copyright © 2011 Dmitrii Samoilov, released under the MIT license
512
576
 
513
577
  Permission is hereby granted, free of charge, to any person obtaining a copy
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * add rake task to create index keys to existing records after the index was added to the column, something like *rake redis_orm:update_index_on zip*
2
+ * add named_scopes
3
+ * Sinatra based admin interface to overview all redis_orm keys in redis
4
+ * ActiveRecord 3.x API
5
+ * refactoring ;)
@@ -0,0 +1,21 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/named_base'
3
+
4
+ module RedisOrm
5
+ module Generators
6
+ class ModelGenerator < ::Rails::Generators::NamedBase
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ desc "Creates a RedisOrm model"
10
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
11
+
12
+ check_class_collision
13
+
14
+ def create_model_file
15
+ template "model.rb.erb", File.join('app/models', class_path, "#{file_name}.rb")
16
+ end
17
+
18
+ hook_for :test_framework
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ class <%= class_name %> < RedisOrm::Base
2
+ <% attributes.each do |attr| %>
3
+ property :<%= attr.name %>, <%= attr.type.to_s.camelcase %>
4
+ <% end -%>
5
+ end
data/lib/redis_orm.rb CHANGED
@@ -1,17 +1,14 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  require 'active_model'
4
2
  require 'redis'
5
3
  require 'uuid'
6
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'active_model_behavior')
7
-
8
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'associations', 'belongs_to')
9
-
10
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'associations', 'has_many_helper')
11
4
 
12
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'associations', 'has_many_proxy')
13
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'associations', 'has_many')
14
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'associations', 'has_one')
5
+ require_relative 'redis_orm/active_model_behavior'
6
+ require_relative 'redis_orm/associations/belongs_to'
7
+ require_relative 'redis_orm/associations/has_many_helper'
8
+ require_relative 'redis_orm/associations/has_many_proxy'
9
+ require_relative 'redis_orm/associations/has_many'
10
+ require_relative 'redis_orm/associations/has_one'
11
+ require_relative 'redis_orm/utils'
15
12
 
16
13
  class String
17
14
  def i18n_key
@@ -23,4 +20,4 @@ class String
23
20
  end
24
21
  end
25
22
 
26
- require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'redis_orm')
23
+ require_relative 'redis_orm/redis_orm'
@@ -1,14 +1,12 @@
1
1
  module ActiveModelBehavior
2
2
  module ClassMethods
3
3
  def model_name
4
- #@_model_name ||= ActiveModel::Name.new(self).to_s.downcase
5
4
  @_model_name ||= ActiveModel::Name.new(self).to_s.tableize.singularize
6
5
  end
7
6
  end
8
7
 
9
8
  module InstanceMethods
10
9
  def model_name
11
- #@_model_name ||= ActiveModel::Name.new(self.class).to_s.downcase
12
10
  @_model_name ||= ActiveModel::Name.new(self.class).to_s.tableize.singularize
13
11
  end
14
12
  end
@@ -14,28 +14,37 @@ module RedisOrm
14
14
  class_associations = class_variable_get(:"@@associations")
15
15
  class_variable_get(:"@@associations")[model_name] << {:type => :belongs_to, :foreign_model => foreign_model, :options => options}
16
16
 
17
- foreign_model_name = if options[:as]
18
- options[:as].to_sym
19
- else
20
- foreign_model.to_sym
17
+ foreign_model_name = options[:as] ? options[:as].to_sym : foreign_model.to_sym
18
+
19
+ if options[:index]
20
+ class_variable_get(:"@@indices")[model_name] << {:name => foreign_model_name, :options => {:reference => true}}
21
21
  end
22
-
23
- define_method foreign_model_name.to_sym do
22
+
23
+ define_method foreign_model_name do
24
24
  if options[:polymorphic]
25
25
  model_type = $redis.get("#{model_name}:#{id}:#{foreign_model_name}_type")
26
26
  if model_type
27
27
  model_type.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}_id")
28
28
  end
29
29
  else
30
- foreign_model.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
30
+ # find model even if it's in some module
31
+ full_model_scope = RedisOrm::Base.descendants.detect{|desc| desc.to_s.split('::').include?(foreign_model.to_s.camelize) }
32
+ if full_model_scope
33
+ full_model_scope.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
34
+ else
35
+ foreign_model.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
36
+ end
31
37
  end
32
38
  end
33
-
39
+
34
40
  # look = Look.create :title => 'test'
35
41
  # look.user = User.find(1) => look:23:user => 1
36
42
  define_method "#{foreign_model_name}=" do |assoc_with_record|
37
43
  # we need to store this to clear old association later
38
44
  old_assoc = self.send(foreign_model_name)
45
+
46
+ # find model even if it's in some module
47
+ full_model_scope = RedisOrm::Base.descendants.detect{|desc| desc.to_s.split('::').include?(foreign_model.to_s.camelize) }
39
48
 
40
49
  if options[:polymorphic]
41
50
  $redis.set("#{model_name}:#{id}:#{foreign_model_name}_type", assoc_with_record.model_name)
@@ -43,13 +52,42 @@ module RedisOrm
43
52
  else
44
53
  if assoc_with_record.nil?
45
54
  $redis.del("#{model_name}:#{id}:#{foreign_model_name}")
46
- elsif assoc_with_record.model_name == foreign_model.to_s
55
+ elsif [foreign_model.to_s, full_model_scope.model_name].include?(assoc_with_record.model_name)
47
56
  $redis.set("#{model_name}:#{id}:#{foreign_model_name}", assoc_with_record.id)
48
57
  else
49
58
  raise TypeMismatchError
50
59
  end
51
60
  end
61
+
62
+ # handle indices for references
63
+ self.get_indices.select{|index| index[:options][:reference]}.each do |index|
64
+ # delete old reference that points to the old associated record
65
+ if !old_assoc.nil?
66
+ prepared_index = [self.model_name, index[:name], old_assoc.id].join(':')
67
+ prepared_index.downcase! if index[:options][:case_insensitive]
68
+
69
+ if index[:options][:unique]
70
+ $redis.del(prepared_index, id)
71
+ else
72
+ $redis.zrem(prepared_index, id)
73
+ end
74
+ end
75
+
76
+ # if new associated record is nil then skip to next index (since old associated record was already unreferenced)
77
+ next if assoc_with_record.nil?
78
+
79
+ prepared_index = [self.model_name, index[:name], assoc_with_record.id].join(':')
80
+
81
+ prepared_index.downcase! if index[:options][:case_insensitive]
82
+
83
+ if index[:options][:unique]
84
+ $redis.set(prepared_index, id)
85
+ else
86
+ $redis.zadd(prepared_index, Time.now.to_f, id)
87
+ end
88
+ end
52
89
 
90
+ # we should have an option to delete created earlier associasion (like 'node.owner = nil')
53
91
  if assoc_with_record.nil?
54
92
  # remove old assoc
55
93
  $redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
@@ -57,7 +95,7 @@ module RedisOrm
57
95
  # 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)
58
96
  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)
59
97
  # remove old assoc
60
- $redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
98
+ $redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
61
99
  assoc_with_record.send(model_name.pluralize.to_sym).send(:"<<", self)
62
100
 
63
101
  # 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)
@@ -70,4 +108,4 @@ module RedisOrm
70
108
  end
71
109
  end
72
110
  end
73
- end
111
+ end
@@ -7,12 +7,8 @@ module RedisOrm
7
7
  def has_many(foreign_models, options = {})
8
8
  class_associations = class_variable_get(:"@@associations")
9
9
  class_associations[model_name] << {:type => :has_many, :foreign_models => foreign_models, :options => options}
10
-
11
- foreign_models_name = if options[:as]
12
- options[:as].to_sym
13
- else
14
- foreign_models.to_sym
15
- end
10
+
11
+ foreign_models_name = options[:as] ? options[:as].to_sym : foreign_models.to_sym
16
12
 
17
13
  define_method foreign_models_name.to_sym do
18
14
  Associations::HasManyProxy.new(model_name, id, foreign_models, options)
@@ -26,9 +22,13 @@ module RedisOrm
26
22
  old_records = self.send(foreign_models).to_a
27
23
  if !old_records.empty?
28
24
  # cache here which association with current model have old record's model
29
- has_many_assoc = old_records[0].get_associations.detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym}
25
+ has_many_assoc = old_records[0].get_associations.detect do |h|
26
+ h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym
27
+ end
30
28
 
31
- has_one_or_belongs_to_assoc = old_records[0].get_associations.detect{|h| [:has_one, :belongs_to].include?(h[:type]) && h[:foreign_model] == model_name.to_sym}
29
+ has_one_or_belongs_to_assoc = old_records[0].get_associations.detect do |h|
30
+ [:has_one, :belongs_to].include?(h[:type]) && h[:foreign_model] == model_name.to_sym
31
+ end
32
32
 
33
33
  old_records.each do |record|
34
34
  if has_many_assoc
@@ -45,23 +45,31 @@ module RedisOrm
45
45
 
46
46
  records.to_a.each do |record|
47
47
  # we use here *foreign_models_name* not *record.model_name.pluralize* because of the :as option
48
- $redis.zadd("#{model_name}:#{id}:#{foreign_models_name}", Time.now.to_f, record.id)
49
-
48
+ key = "#{model_name}:#{id}:#{foreign_models_name}"
49
+ $redis.zadd(key, Time.now.to_f, record.id)
50
+ set_expire_on_reference_key(key)
51
+
50
52
  record.get_indices.each do |index|
51
53
  save_index_for_associated_record(index, record, [model_name, id, record.model_name.pluralize]) # record.model_name.pluralize => foreign_models_name
52
54
  end
53
55
 
54
- if !options[:as]
55
- # article.comments = [comment1, comment2]
56
- # iterate through the array of comments and create backlink
57
- # check whether *record* object has *has_many* declaration and TODO it states *self.model_name* in plural
58
- if class_associations[record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} #&& !$redis.zrank("#{record.model_name}:#{record.id}:#{model_name.pluralize}", id)#record.model_name.to_s.camelize.constantize.find(id).nil?
59
- $redis.zadd("#{record.model_name}:#{record.id}:#{model_name.pluralize}", Time.now.to_f, id)
60
- # check whether *record* object has *has_one* declaration and TODO it states *self.model_name*
61
- elsif record.get_associations.detect{|h| [:has_one, :belongs_to].include?(h[:type]) && h[:foreign_model] == model_name.to_sym}
62
- # overwrite assoc anyway so we don't need to check record.send(model_name.to_sym).nil? here
63
- $redis.set("#{record.model_name}:#{record.id}:#{model_name}", id)
64
- end
56
+ # article.comments = [comment1, comment2]
57
+ # iterate through the array of comments and create backlink
58
+ # check whether *record* object has *has_many* declaration and it states *self.model_name* in plural
59
+ if assoc = class_associations[record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} #&& !$redis.zrank("#{record.model_name}:#{record.id}:#{model_name.pluralize}", id)#record.model_name.to_s.camelize.constantize.find(id).nil?
60
+ assoc_foreign_models_name = assoc[:options][:as] ? assoc[:options][:as] : model_name.pluralize
61
+ key = "#{record.model_name}:#{record.id}:#{assoc_foreign_models_name}"
62
+ $redis.zadd(key, Time.now.to_f, id) if !$redis.zrank(key, id)
63
+ set_expire_on_reference_key(key)
64
+ end
65
+
66
+ # check whether *record* object has *has_one* declaration and it states *self.model_name*
67
+ if assoc = record.get_associations.detect{|h| [:has_one, :belongs_to].include?(h[:type]) && h[:foreign_model] == model_name.to_sym}
68
+ foreign_model_name = assoc[:options][:as] ? assoc[:options][:as] : model_name
69
+ key = "#{record.model_name}:#{record.id}:#{foreign_model_name}"
70
+ # overwrite assoc anyway so we don't need to check record.send(model_name.to_sym).nil? here
71
+ $redis.set(key, id)
72
+ set_expire_on_reference_key(key)
65
73
  end
66
74
  end
67
75
  end
@@ -1,7 +1,7 @@
1
1
  module RedisOrm
2
2
  module Associations
3
3
  module HasManyHelper
4
- private
4
+ private
5
5
  def save_index_for_associated_record(index, record, inception)
6
6
  prepared_index = if index[:name].is_a?(Array) # TODO sort alphabetically
7
7
  index[:name].inject(inception) do |sum, index_part|
@@ -3,15 +3,19 @@ module RedisOrm
3
3
  class HasManyProxy
4
4
  include HasManyHelper
5
5
 
6
- def initialize(reciever_model_name, reciever_id, foreign_models, options)
6
+ def initialize(receiver_model_name, reciever_id, foreign_models, options)
7
7
  @records = [] #records.to_a
8
- @reciever_model_name = reciever_model_name
8
+ @reciever_model_name = receiver_model_name
9
9
  @reciever_id = reciever_id
10
10
  @foreign_models = foreign_models
11
11
  @options = options
12
12
  @fetched = false
13
13
  end
14
14
 
15
+ def receiver_instance
16
+ @receiver_instance ||= @reciever_model_name.camelize.constantize.find(@reciever_id)
17
+ end
18
+
15
19
  def fetch
16
20
  @records = @foreign_models.to_s.singularize.camelize.constantize.find($redis.zrevrangebyscore __key__, Time.now.to_f, 0)
17
21
  @fetched = true
@@ -31,8 +35,10 @@ module RedisOrm
31
35
  # user.avatars << Avatar.find(23) => user:1:avatars => [23]
32
36
  def <<(new_records)
33
37
  new_records.to_a.each do |record|
34
- $redis.zadd(__key__, Time.now.to_f, record.id)
35
-
38
+ $redis.zadd(__key__, Time.now.to_f, record.id)
39
+
40
+ receiver_instance.set_expire_on_reference_key(__key__)
41
+
36
42
  record.get_indices.each do |index|
37
43
  save_index_for_associated_record(index, record, [@reciever_model_name, @reciever_id, record.model_name.pluralize]) # record.model_name.pluralize => @foreign_models
38
44
  end
@@ -50,8 +56,11 @@ module RedisOrm
50
56
  @reciever_model_name.pluralize
51
57
  end
52
58
 
53
- if !$redis.zrank("#{record.model_name}:#{record.id}:#{pluralized_reciever_model_name}", @reciever_id)
54
- $redis.zadd("#{record.model_name}:#{record.id}:#{pluralized_reciever_model_name}", Time.now.to_f, @reciever_id)
59
+ reference_key = "#{record.model_name}:#{record.id}:#{pluralized_reciever_model_name}"
60
+
61
+ if !$redis.zrank(reference_key, @reciever_id)
62
+ $redis.zadd(reference_key, Time.now.to_f, @reciever_id)
63
+ receiver_instance.set_expire_on_reference_key(reference_key)
55
64
  end
56
65
  # check whether *record* object has *has_one* declaration and TODO it states *self.model_name* and there is no record yet from the *record*'s side (in order not to provoke recursion)
57
66
  elsif has_one_assoc = record_associations.detect{|h| [:has_one, :belongs_to].include?(h[:type]) && h[:foreign_model] == @reciever_model_name.to_sym}
@@ -61,7 +70,9 @@ module RedisOrm
61
70
  @reciever_model_name
62
71
  end
63
72
  if record.send(reciever_model_name).nil?
64
- $redis.set("#{record.model_name}:#{record.id}:#{reciever_model_name}", @reciever_id)
73
+ key = "#{record.model_name}:#{record.id}:#{reciever_model_name}"
74
+ $redis.set(key, @reciever_id)
75
+ receiver_instance.set_expire_on_reference_key(key)
65
76
  end
66
77
  end
67
78
  end
@@ -82,7 +93,7 @@ module RedisOrm
82
93
  prepared_index = if options[:conditions] && options[:conditions].is_a?(Hash)
83
94
  properties = options[:conditions].collect{|key, value| key}
84
95
 
85
- index = @foreign_models.to_s.singularize.camelize.constantize.find_index(properties)
96
+ index = @foreign_models.to_s.singularize.camelize.constantize.find_indices(properties, :first => true)
86
97
 
87
98
  raise NotIndexFound if !index
88
99