module StewEucen::Acts::FertileForest::Table
Name space of class methods for Fertile Forest
Name space of class methods for Fertile Forest
Name space of class methods for Fertile Forest
Name space of class methods for Fertile Forest
Name space of class methods for Fertile Forest
Name space of class methods for Fertile Forest
Table
Methods to extend into ActiveRecord class.
@author StewEucen
@example Extend into ActiveRecord class.
ActiveRecord::Base.send :extend, StewEucen::Acts::FertileForest::Table
@since Release 1.0.0
Public Instance Methods
acts_as_fertile_forest(options = {})
click to toggle source
Initializer for eech model.
@author StewEucen
@example You write this method in a model of Rails as follows.
class Category < ActiveRecord::Base acts_as_fertile_forest end # When use alias name of columns as: acts_as_fertile_forest({ aliases: { ff_queue: :queue, ff_depth: :depth, ff_grove: :user_id, ff_soft_deleted: :deleted, } })
@param options [Hash] Fertile Forest's options. @since Release 1.0.0
# File lib/fertile_forest/saplings.rb, line 106 def acts_as_fertile_forest(options = {}) # To use these modules in case fertile forest only. extend Configs extend Utilities extend Calculators extend Finders extend Reconstructers extend States # To change instance of ActiveRecord to Fertile Forest entity. include Entity ff_parse_options! options ff_resolve_alias_columns! # can set attr_accessor here attr_accessor :ff_kinship attr_accessor APPEND_BASE_ID_FIELD attr_accessor :ff_grove unless has_grove? ff_define_scopes! ff_define_alias_methods! ff_define_callbacks! end
Private Instance Methods
ff_all_optional_columns(optional_columns = nil)
click to toggle source
# File lib/fertile_forest/saplings.rb, line 310 def ff_all_optional_columns(optional_columns = nil) optional_columns ||= column_names required_columns = [@_id, @_ff_grove, @_ff_depth, @_ff_queue] regexp_string = required_columns .map { |column| column.to_s } .join('|') delete_regexp = /#{regexp_string}/i # return value (must be Array). optional_columns.delete_if do |column| delete_regexp.match(column) end end
ff_create_subquery_string_to_find_tail_queue(aim_node)
click to toggle source
# File lib/fertile_forest/saplings.rb, line 325 def ff_create_subquery_string_to_find_tail_queue(aim_node) ffqq = arel_table[@_ff_queue] ffdd = arel_table[@_ff_depth] ff_usual_projection(aim_node.ff_grove) .project(ffqq.minimum.to_sql + " - 1 AS boundary_queue") .where(ffdd.lteq(aim_node.ff_depth)) .where(ffqq.gt(aim_node.ff_queue)) end
ff_create_usual_conditions_hash(grove_id = nil)
click to toggle source
# File lib/fertile_forest/saplings.rb, line 294 def ff_create_usual_conditions_hash(grove_id = nil) res = {} res[:ff_soft_delete] = ff_options[:enable_value] \ if has_soft_delete? if has_grove? if grove_id.present? res[:ff_grove] = grove_id else res['ff_grove >='] = 0 if enable_grove_delete? end end res end
ff_default_options()
click to toggle source
# File lib/fertile_forest/saplings.rb, line 169 def ff_default_options { virtual_columns: { ff_base_id: 'ff_base_id', }, enable_value: 0, delete_value: 1, enable_grove_delete: true, subtree_limit_size: 1000, }.freeze end
ff_define_alias_methods!()
click to toggle source
# File lib/fertile_forest/saplings.rb, line 155 def ff_define_alias_methods! # Alias of ActiveRecord::Base::save. # @see ActiveRecord::Base::save. alias_method :sprout, :save end
ff_define_callbacks!()
click to toggle source
# File lib/fertile_forest/saplings.rb, line 161 def ff_define_callbacks! before_create :ff_before_create # must be an instance method before_save :ff_before_save after_save :ff_after_save before_destroy :ff_before_destroy end
ff_define_scopes!()
click to toggle source
# File lib/fertile_forest/saplings.rb, line 190 def ff_define_scopes! scope :ff_usual_conditions_scope, ->(grove_id = nil) do grove_id ||= 0 conditions = all conditions.where!(ff_soft_delete: ff_options[:enable_value]) \ if has_soft_delete? if has_grove? if 0 < grove_id conditions.where!(ff_grove: grove_id) else conditions.where!(arel_table[@_ff_grove].gteq(0)) \ if enable_grove_delete? end end conditions end scope :ff_usual_order_scope, ->(is_descendant = false, is_depth_index = ORDER_BY_QUEUE_INDEX) do direction = is_descendant ? ' DESC' : ' ASC' aim_orders = []; aim_orders << @_ff_soft_delete + direction if has_soft_delete? aim_orders << @_ff_grove + direction if has_grove? aim_orders << @_ff_depth + direction if is_depth_index aim_orders << @_ff_queue + direction order(aim_orders.join(', ')) end scope :ff_required_columns_scope, ->(add_columns = nil) do columns = [@_id, @_ff_queue, @_ff_depth] columns << @_ff_grove if has_grove? columns += add_columns if add_columns.present? select(columns) end scope :ff_subtree_scope, ->(base_node, with_top = false, use_coalesce = false) do return nil if base_node.blank? ffqq = arel_table[@_ff_queue] ffdd = arel_table[@_ff_depth] ffgg = arel_table[@_ff_grove] compair = with_top ? :gteq : :gt aim_query = ff_usual_conditions_scope(base_node.ff_grove) .where(ffqq.send(compair, base_node.ff_queue)) if use_coalesce # TODO: methodize subquery = ff_create_subquery_string_to_find_tail_queue(base_node) func_maker = Arel::Nodes::NamedFunction coalesce_condition = func_maker.new('COALESCE', [subquery, QUEUE_MAX_VALUE]) aim_query.where!(ffqq.lteq(coalesce_condition)) else boundary_queue = ff_get_boundary_queue(base_node) if boundary_queue.blank? # need this conditions for leaves @dd = ffdd. aim_query.where!(ffqq.lteq(QUEUE_MAX_VALUE)) else aim_query.where!(ffqq.lt(boundary_queue)) end end aim_query end # boundary node onditions scope # tail node onditions scope # pre nodes conditions scope end
ff_parse_options!(options)
click to toggle source
# File lib/fertile_forest/saplings.rb, line 183 def ff_parse_options!(options) options = ff_default_options.merge(options) class_attribute :ff_options self.ff_options = options end
ff_resolve_alias_columns!()
click to toggle source
# File lib/fertile_forest/saplings.rb, line 133 def ff_resolve_alias_columns! # aliases of ff_xxxxx 2015/05/27 if ff_options[:aliases].present? ff_options[:aliases].each_pair do |ff_alias, ff_origin| alias_attribute ff_alias, ff_origin end end ff_required_columns = [ 'id', 'ff_grove', 'ff_depth', 'ff_queue', 'ff_soft_delete', 'ff_branch_level', ] ff_required_columns.each do |key| instance_variable_set('@_' + key, attribute_aliases[key] || key) end end
ff_usual_projection(grove_id = nil)
click to toggle source
# File lib/fertile_forest/saplings.rb, line 270 def ff_usual_projection(grove_id = nil) res = arel_table.project() res = res.where(arel_table[@_ff_soft_delete].eq(ff_options[:enable_value])) \ if has_soft_delete? if has_grove? ffgg = arel_table[@_ff_grove] if grove_id.present? # res = res.send :where, {@_ff_grove => grove_id} if grove_id.instance_of?(Array) res = res.where(ffgg.in(grove_id)) else res = res.where(ffgg.eq(grove_id)) end else res = res.where(ffgg.gteq(0)) \ if enable_grove_delete? end end res end