module RedisOrm::Associations::BelongsTo
Public Instance Methods
belongs_to(foreign_model, options = {})
click to toggle source
class Avatar < RedisOrm::Base
belongs_to :user
end
class User < RedisOrm::Base
has_many :avatars
end
avatar.user => avatar:234:user => 1 => User.find(1)
# File lib/redis_orm/associations/belongs_to.rb 13 def belongs_to(foreign_model, options = {}) 14 class_associations = class_variable_get(:"@@associations") 15 class_variable_get(:"@@associations")[model_name] << {:type => :belongs_to, :foreign_model => foreign_model, :options => options} 16 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 end 22 23 define_method foreign_model_name do 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 # 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 37 end 38 end 39 40 # look = Look.create :title => 'test' 41 # look.user = User.find(1) => look:23:user => 1 42 define_method "#{foreign_model_name}=" do |assoc_with_record| 43 # we need to store this to clear old association later 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) } 48 49 if options[:polymorphic] 50 $redis.set("#{model_name}:#{id}:#{foreign_model_name}_type", assoc_with_record.model_name) 51 $redis.set("#{model_name}:#{id}:#{foreign_model_name}_id", assoc_with_record.id) 52 else 53 if assoc_with_record.nil? 54 $redis.del("#{model_name}:#{id}:#{foreign_model_name}") 55 elsif [foreign_model.to_s, full_model_scope.model_name].include?(assoc_with_record.model_name) 56 $redis.set("#{model_name}:#{id}:#{foreign_model_name}", assoc_with_record.id) 57 else 58 raise TypeMismatchError 59 end 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 89 90 # we should have an option to delete created earlier associasion (like 'node.owner = nil') 91 if assoc_with_record.nil? 92 # remove old assoc 93 $redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc 94 else 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) 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) 97 # remove old assoc 98 $redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc 99 assoc_with_record.send(model_name.pluralize.to_sym).send(:"<<", self) 100 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) 102 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? 103 # old association is being rewritten here automatically so we don't have to worry about it 104 assoc_with_record.send("#{model_name}=", self) 105 end 106 end 107 end 108 end