module Mongoid::Denormalize
Constants
- VERSION
Public Class Methods
add_hook_to_child(child_class, fields, options)
click to toggle source
Add hook to child class to denormalize fields when parent relation is changed
# File lib/mongoid-denormalize.rb, line 54 def self.add_hook_to_child(child_class, fields, options) from = options[:from].to_s child_class.send(options[:child_callback] || 'before_save') do if send("#{from}_id_changed?") fields.each do |field| send("#{field[:as]}=", send(from)&.send(field[:name])) end end end end
add_hook_to_parent(child_class, fields, options)
click to toggle source
Add hook to parent class to denormalize fields when parent object is updated
# File lib/mongoid-denormalize.rb, line 67 def self.add_hook_to_parent(child_class, fields, options) from = options[:from].to_s parent = parent_class(child_class, from) relation = parent.relations[child_class.relations[from].inverse_of.to_s] || parent.relations[child_class.model_name.plural] || parent.relations[child_class.model_name.singular] unless relation raise "Option :inverse_of is needed for 'belongs_to :#{from}' into #{child_class}." end parent.after_update do attributes = {} fields.each do |field| attributes[field[:as]] = send(field[:name]) if send("#{field[:name]}_changed?") end next if attributes.blank? case relation.relation.to_s when 'Mongoid::Relations::Referenced::One', 'Mongoid::Association::Referenced::HasOne::Proxy' if (document = send(relation.name)) document.collection.update_one({_id: document._id}, {'$set' => attributes}) end when 'Mongoid::Relations::Referenced::Many', 'Mongoid::Association::Referenced::HasMany::Proxy' send(relation.name).update_all('$set' => attributes) else raise "Relation type unsupported: #{relation.relation}" end end end
field_type(klass, field)
click to toggle source
Retreive the type of a field from the given class
# File lib/mongoid-denormalize.rb, line 109 def self.field_type(klass, field) klass.fields[field.to_s].options[:type] end
get_fields_with_names(child_class, fields, options)
click to toggle source
Check options and return name for each field
# File lib/mongoid-denormalize.rb, line 29 def self.get_fields_with_names(child_class, fields, options) parent = parent_class(child_class, options[:from].to_s) if options.include?(:as) options[:as] = [options[:as]] unless options[:as].is_a?(Array) unless fields.size == options[:as].size raise ArgumentError, 'When option :as is used you must pass a name for each field.' end return fields.map.with_index do |field, index| {name: field, as: options[:as][index], type: field_type(parent, field)} end elsif options.include?(:prefix) return fields.map do |field| {name: field, as: "#{options[:prefix]}_#{field}", type: field_type(parent, field)} end end fields.map do |field| {name: field, as: "#{options[:from]}_#{field}", type: field_type(parent, field)} end end
included(base)
click to toggle source
# File lib/mongoid-denormalize.rb, line 5 def self.included(base) base.extend ClassMethods end
parent_class(child_class, from)
click to toggle source
Retrieve parent class
# File lib/mongoid-denormalize.rb, line 103 def self.parent_class(child_class, from) (child_class.relations[from].class_name || child_class.relations[from].name.capitalize) .constantize end