module RedisOrm::Associations::HasMany
Public Instance Methods
has_many(foreign_models, options = {})
click to toggle source
user.avatars => user:1:avatars => [1, 22, 234] => Avatar.find([1, 22, 234]) options
*:dependant* key: either *destroy* or *nullify* (default)
# File lib/redis_orm/associations/has_many.rb 7 def has_many(foreign_models, options = {}) 8 class_associations = class_variable_get(:"@@associations") 9 class_associations[model_name] << {:type => :has_many, :foreign_models => foreign_models, :options => options} 10 11 foreign_models_name = options[:as] ? options[:as].to_sym : foreign_models.to_sym 12 13 define_method foreign_models_name.to_sym do 14 Associations::HasManyProxy.new(model_name, id, foreign_models, options) 15 end 16 17 # user = User.find(1) 18 # user.avatars = Avatar.find(23) => user:1:avatars => [23] 19 define_method "#{foreign_models_name}=" do |records| 20 if !options[:as] 21 # clear old assocs from related models side 22 old_records = self.send(foreign_models).to_a 23 if !old_records.empty? 24 # cache here which association with current model have old record's model 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 28 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 33 old_records.each do |record| 34 if has_many_assoc 35 $redis.zrem "#{record.model_name}:#{record.id}:#{model_name.pluralize}", id 36 elsif has_one_or_belongs_to_assoc 37 $redis.del "#{record.model_name}:#{record.id}:#{model_name}" 38 end 39 end 40 end 41 42 # clear old assocs from this model side 43 $redis.zremrangebyscore "#{model_name}:#{id}:#{foreign_models}", 0, Time.now.to_f 44 end 45 46 records.to_a.each do |record| 47 # we use here *foreign_models_name* not *record.model_name.pluralize* because of the :as option 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 52 record.get_indices.each do |index| 53 save_index_for_associated_record(index, record, [model_name, id, record.model_name.pluralize]) # record.model_name.pluralize => foreign_models_name 54 end 55 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) 73 end 74 end 75 end 76 end