class RedisOrm::Associations::HasManyProxy
Public Class Methods
new(receiver_model_name, reciever_id, foreign_models, options)
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 6 def initialize(receiver_model_name, reciever_id, foreign_models, options) 7 @records = [] #records.to_a 8 @reciever_model_name = receiver_model_name 9 @reciever_id = reciever_id 10 @foreign_models = foreign_models 11 @options = options 12 @fetched = false 13 end
Public Instance Methods
<<(new_records)
click to toggle source
user = User.find(1) user.avatars << Avatar.find(23) => user:1:avatars => [23]
# File lib/redis_orm/associations/has_many_proxy.rb 36 def <<(new_records) 37 new_records.to_a.each do |record| 38 $redis.zadd(__key__, Time.now.to_f, record.id) 39 40 receiver_instance.set_expire_on_reference_key(__key__) 41 42 record.get_indices.each do |index| 43 save_index_for_associated_record(index, record, [@reciever_model_name, @reciever_id, record.model_name.pluralize]) # record.model_name.pluralize => @foreign_models 44 end 45 46 if !@options[:as] 47 record_associations = record.get_associations 48 49 # article.comments << [comment1, comment2] 50 # iterate through the array of comments and create backlink 51 # check whether *record* object has *has_many* declaration and TODO it states *self.model_name* in plural and there is no record yet from the *record*'s side (in order not to provoke recursion) 52 if has_many_assoc = record_associations.detect{|h| h[:type] == :has_many && h[:foreign_models] == @reciever_model_name.pluralize.to_sym} 53 pluralized_reciever_model_name = if has_many_assoc[:options][:as] 54 has_many_assoc[:options][:as].pluralize 55 else 56 @reciever_model_name.pluralize 57 end 58 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) 64 end 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) 66 elsif has_one_assoc = record_associations.detect{|h| [:has_one, :belongs_to].include?(h[:type]) && h[:foreign_model] == @reciever_model_name.to_sym} 67 reciever_model_name = if has_one_assoc[:options][:as] 68 has_one_assoc[:options][:as].to_sym 69 else 70 @reciever_model_name 71 end 72 if record.send(reciever_model_name).nil? 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) 76 end 77 end 78 end 79 end 80 81 # return *self* here so calls could be chained 82 self 83 end
[](index)
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 24 def [](index) 25 fetch if !@fetched 26 @records[index] 27 end
all(options = {})
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 85 def all(options = {}) 86 if options.is_a?(Hash) && (options[:limit] || options[:offset] || options[:order] || options[:conditions]) 87 limit = if options[:limit] && options[:offset] 88 [options[:offset].to_i, options[:limit].to_i] 89 elsif options[:limit] 90 [0, options[:limit].to_i] 91 end 92 93 prepared_index = if options[:conditions] && options[:conditions].is_a?(Hash) 94 properties = options[:conditions].collect{|key, value| key} 95 96 index = @foreign_models.to_s.singularize.camelize.constantize.find_indices(properties, :first => true) 97 98 raise NotIndexFound if !index 99 100 construct_prepared_index(index, options[:conditions]) 101 else 102 __key__ 103 end 104 105 @records = [] 106 107 # to DRY things up I use here check for index but *else* branch also imply that the index might have be used 108 # since *prepared_index* vary whether options[:conditions] are present or not 109 if index && index[:options][:unique] 110 id = $redis.get prepared_index 111 @records << @foreign_models.to_s.singularize.camelize.constantize.find(id) 112 else 113 ids = if options[:order].to_s == 'desc' 114 $redis.zrevrangebyscore(prepared_index, Time.now.to_f, 0, :limit => limit) 115 else 116 $redis.zrangebyscore(prepared_index, 0, Time.now.to_f, :limit => limit) 117 end 118 @records += @foreign_models.to_s.singularize.camelize.constantize.find(ids) 119 end 120 @fetched = true 121 @records 122 else 123 fetch if !@fetched 124 @records 125 end 126 end
count()
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 151 def count 152 $redis.zcard __key__ 153 end
delete(id)
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 147 def delete(id) 148 $redis.zrem(__key__, id.to_i) 149 end
fetch()
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 19 def fetch 20 @records = @foreign_models.to_s.singularize.camelize.constantize.find($redis.zrevrangebyscore __key__, Time.now.to_f, 0) 21 @fetched = true 22 end
find(token = nil, options = {})
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 128 def find(token = nil, options = {}) 129 if token.is_a?(String) || token.is_a?(Integer) 130 record_id = $redis.zrank(__key__, token.to_i) 131 if record_id 132 @fetched = true 133 @records = @foreign_models.to_s.singularize.camelize.constantize.find(token) 134 else 135 nil 136 end 137 elsif token == :all 138 all(options) 139 elsif token == :first 140 all(options.merge({:limit => 1}))[0] 141 elsif token == :last 142 reversed = options[:order] == 'desc' ? 'asc' : 'desc' 143 all(options.merge({:limit => 1, :order => reversed}))[0] 144 end 145 end
method_missing(method_name, *args, &block)
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 155 def method_missing(method_name, *args, &block) 156 fetch if !@fetched 157 @records.send(method_name, *args, &block) 158 end
receiver_instance()
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 15 def receiver_instance 16 @receiver_instance ||= @reciever_model_name.camelize.constantize.find(@reciever_id) 17 end
to_a()
click to toggle source
# File lib/redis_orm/associations/has_many_proxy.rb 29 def to_a 30 fetch if !@fetched 31 @records 32 end
Protected Instance Methods
__key__()
click to toggle source
helper method
# File lib/redis_orm/associations/has_many_proxy.rb 163 def __key__ 164 @options[:as] ? "#{@reciever_model_name}:#{@reciever_id}:#{@options[:as]}" : "#{@reciever_model_name}:#{@reciever_id}:#{@foreign_models}" 165 end
construct_prepared_index(index, conditions_hash)
click to toggle source
“article:1:comments:moderated:true”
# File lib/redis_orm/associations/has_many_proxy.rb 168 def construct_prepared_index(index, conditions_hash) 169 prepared_index = [@reciever_model_name, @reciever_id, @foreign_models].join(':') 170 171 # in order not to depend on order of keys in *:conditions* hash we rather interate over the index itself and find corresponding values in *:conditions* hash 172 if index[:name].is_a?(Array) 173 index[:name].each do |key| 174 # raise if User.find_by_firstname_and_castname => there's no *castname* in User's properties 175 #raise ArgumentsMismatch if !@@properties[model_name].detect{|p| p[:name] == key.to_sym} # TODO 176 prepared_index += ":#{key}:#{conditions_hash[key]}" 177 end 178 else 179 prepared_index += ":#{index[:name]}:#{conditions_hash[index[:name]]}" 180 end 181 182 prepared_index.downcase! if index[:options][:case_insensitive] 183 184 prepared_index 185 end