module Bodhi::Associations::ClassMethods
Public Instance Methods
associations()
click to toggle source
# File lib/bodhi-slam/associations.rb, line 4 def associations; @associations; end
belongs_to(association_name, options={})
click to toggle source
# File lib/bodhi-slam/associations.rb, line 116 def belongs_to(association_name, options={}) options = Bodhi::Support.symbolize_keys(options) define_association(:belongs_to, association_name, options) # Define a new helper method to get the association define_method(association_name) do # Get the value from the instance object's source_key. Default is :sys_id association = self.class.associations[association_name.to_sym] instance_id = self.send(association[:primary_key]) # Define & call the query. Returns a single Object or nil query = Bodhi::Query.new(association[:class_name]).from(self.bodhi_context) query.where(association[:foreign_key].to_sym => instance_id) query.and(association[:query]) puts query.url query.first end end
has_many(association_name, options={})
click to toggle source
# File lib/bodhi-slam/associations.rb, line 37 def has_many(association_name, options={}) options = Bodhi::Support.symbolize_keys(options) define_association(:has_many, association_name, options) # Define a new helper method to get the association define_method(association_name) do # Get the value from the instance object's source_key. Default is :sys_id association = self.class.associations[association_name.to_sym] query = Bodhi::Query.new(association[:class_name]).from(self.bodhi_context) if association[:through] through_query = Bodhi::Query.new(association[:through][:class_name]).from(self.bodhi_context) through_query.where(association[:through][:foreign_key].to_sym => self.send(association[:primary_key])) through_query.select(association[:through][:primary_key]) count = through_query.count pages = (count.to_f / 100.0).ceil instance_ids = [] method_chain = association[:through][:primary_key].split('.') # loop through each page of the through query if pages > 0 pages.times.collect do |n| paged_query = through_query.clone paged_query.page(n+1) puts paged_query.url records = paged_query.all instance_ids << records.map{ |item| method_chain.reduce(item){ |memo, method| memo.send(method) } } end instance_ids.flatten!.uniq! end # partition the target query if larger than 4K test_query = query.clone query_size = test_query.where(association[:foreign_key].to_sym => { "$in" => instance_ids }).and(association[:query]).url.bytesize if query_size > 4000 records = [] instance_ids.each_slice(100) do |slice| sliced_query = query.clone sliced_query.where(association[:foreign_key].to_sym => { "$in" => slice }) sliced_query.and(association[:query]) puts sliced_query.url records << sliced_query.all end records.flatten! return records else query.where(association[:foreign_key].to_sym => { "$in" => instance_ids }) query.and(association[:query]) puts query.url return query.all end else # default :has_many flow instance_id = self.send(association[:primary_key]) if instance_id.is_a?(Array) query.where(association[:foreign_key].to_sym => { "$in" => instance_id }) else query.where(association[:foreign_key].to_sym => instance_id) end query.and(association[:query]) puts query.url return query.all end end end
has_one(association_name, options={})
click to toggle source
# File lib/bodhi-slam/associations.rb, line 6 def has_one(association_name, options={}) options = Bodhi::Support.symbolize_keys(options) define_association(:has_one, association_name, options) # Define a new helper method to get the association define_method(association_name) do association = self.class.associations[association_name.to_sym] query = Bodhi::Query.new(association[:class_name]).from(self.bodhi_context) if association[:through] through_query = Bodhi::Query.new(association[:through][:class_name]).from(self.bodhi_context) through_query.where(association[:through][:foreign_key].to_sym => self.send(association[:primary_key])) through_query.select(association[:through][:primary_key]) puts through_query.url instance_id = through_query.first.send(association[:through][:primary_key]) query.where(association[:foreign_key].to_sym => instance_id) else instance_id = self.send(association[:primary_key]) query.where(association[:foreign_key].to_sym => instance_id) end query.and(association[:query]) puts query.url query.first end end
Private Instance Methods
define_association(type, name, options)
click to toggle source
# File lib/bodhi-slam/associations.rb, line 138 def define_association(type, name, options) options.merge!(association_type: type) if options[:class_name].nil? options[:class_name] = Bodhi::Support.camelize(name.to_s) end if options[:through].is_a?(String) case options[:association_type] when :has_one options[:through] = { class_name: Bodhi::Support.camelize(options[:through]), foreign_key: Bodhi::Support.underscore(self.name)+"_id", primary_key: "sys_id" } options[:foreign_key] = Bodhi::Support.underscore(options[:through][:class_name])+"_id" when :has_many options[:through] = { class_name: Bodhi::Support.camelize(options[:through]), foreign_key: Bodhi::Support.underscore(self.name)+"_id", primary_key: Bodhi::Support.underscore(options[:class_name])+"_id" } options[:foreign_key] = "sys_id" end end case type when :belongs_to if options[:foreign_key].nil? options[:foreign_key] = "sys_id" end if options[:primary_key].nil? options[:primary_key] = Bodhi::Support.underscore(options[:class_name])+"_id" end else if options[:foreign_key].nil? options[:foreign_key] = Bodhi::Support.underscore(self.name)+"_id" end if options[:primary_key].nil? options[:primary_key] = "sys_id" end end options[:query].nil? ? options[:query] = Hash.new : options[:query] @associations[name.to_sym] = options end