module Mongoid::SleepingKingStudios::HasTree
Adds a belongs_to parent relation and a has_many children relation to set up a basic tree structure, as well as several helper methods.
@note From 0.2.0 to 0.3.1, was Mongoid::SleepingKingStudios::Tree.
@example Setting up the tree:
class SluggableDocument include Mongoid::Document include Mongoid::SleepingKingStudios::Tree has_tree end # class
Since 0.4.1, you must call the class method ::has_tree in order to set up the parent and children relations. You can pass optional parameters into this method to customise the created relations, including the names of the relations.
@example Setting up the tree with alternate relation names:
class EvilEmployee include Mongoid::Document include Mongoid::SleepingKingStudios::Tree has_tree :parent => { :relation_name => 'overlord' }, :children => { :relation_name => 'minions', :dependent => :destroy } end # class
@since 0.2.0
Public Class Methods
@api private
Sets up the has_tree relation, creating fields, accessors and validations.
@param [Class] base The base class into which the concern is mixed in. @param [Hash] options The options for the relation.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/has_tree.rb, line 50 def self.apply base, options options[:parent] ||= {} options[:children] ||= {} options[:parent][:inverse_of] = options[:children].fetch(:relation_name, :children) options[:children][:inverse_of] = options[:parent].fetch(:relation_name, :parent) name = :has_tree validate_options name, options meta = characterize name, options, Metadata relate base, name, meta define_relations base, meta define_helpers base, meta if meta.cache_ancestry? concern = Mongoid::SleepingKingStudios::HasTree::CacheAncestry concern.send :apply, base, meta.cache_ancestry end # if end
@api private
Sets up the helper methods for the relations as follows.
Defines the following class methods:
-
::roots
Defines the following instance methods:
-
leaf?
-
root
-
root?
@param [Class] base The base class into which the concern is mixed in. @param [Metadata] metadata The metadata for the relation.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/has_tree.rb, line 88 def self.define_helpers base, metadata base.metaclass.send :define_method, :roots do where({ :"#{metadata.parent.relation_name}_id" => nil }) end # class method roots base.send :define_method, :root do parent = send(metadata.parent.relation_name) parent ? parent.root : self end # method root base.send :define_method, :leaf? do send(metadata.children.relation_name).blank? end # method root? base.send :define_method, :root? do send(metadata.parent.relation_name).nil? end # method root? base.send :define_method, :siblings do self.class.where(:id => { "$ne" => self.id }).where(metadata.foreign_key => self.send(metadata.foreign_key)) end # method siblings end
@api private
Sets up the parent and children relations.
@param [Class] base The base class into which the concern is mixed in. @param [Metadata] metadata The metadata for the relation.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/has_tree.rb, line 119 def self.define_relations base, metadata parent_options = metadata.parent.properties.dup parent_options.update :class_name => base.name parent_options.delete :relation_name children_options = metadata.children.properties.dup children_options.update :class_name => base.name children_options.delete :relation_name base.belongs_to metadata.parent.relation_name, parent_options base.has_many metadata.children.relation_name, children_options end
Get the valid options allowed with this concern.
@return [ Array<Symbol> ] The valid options.
@since 0.4.1
# File lib/mongoid/sleeping_king_studios/has_tree.rb, line 137 def self.valid_options %i( cache_ancestry children parent ) # end Array end