Module: Ext::Taxon

Defined in:
app/models/com/ext/taxon.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(model) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'app/models/com/ext/taxon.rb', line 7

def self.included(model)
  if model.table_exists? && model.column_names.include?('position')
    model.has_closure_tree order: 'position'
  else
    model.has_closure_tree
  end
  model.include Com::Ext::TaxonPrepend

  model.attribute :parent_ancestors, :json, default: {}
  model.before_validation :sync_parent_id, if: -> { parent_ancestors_changed? && (parent_ancestors.presence != parent_ancestors_was.presence) }
  model.before_validation :set_parent_ancestors, if: -> { parent.present? && parent_ancestors.blank? }  # todo 考虑 parent 改变的情况
  model.hierarchy_class.attribute :generations, :integer, null: false
  model.hierarchy_class.attribute :created_at, :datetime, null: true  # 需要 created_at/updated_at 可为空值
  model.hierarchy_class.attribute :updated_at, :datetime, null: true
  model.hierarchy_class.index [:ancestor_id, :descendant_id, :generations], unique: true, name: "#{model.name.underscore}_anc_desc_idx"

  def model.max_depth
    self.hierarchy_class.maximum(:generations).to_i + 1
  end

  def model.extract_multi_attributes(pairs)
    _pairs = pairs.select { |k, _| k.include?('(') }
    _real = {}
    r = self.new.send :extract_callstack_for_multiparameter_attributes, _pairs
    r.each do |k, v|
      _real[k.sub(/ancestors$/, 'id')] = v.values.compact.last
    end
    _real
  end
end

Instance Method Details

#depth_strObject



38
39
40
# File 'app/models/com/ext/taxon.rb', line 38

def depth_str
  (0..self.class.max_depth - self.depth).to_a.reverse.join
end

#middle?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'app/models/com/ext/taxon.rb', line 55

def middle?
  parent_id.present? && depth < self.class.max_depth
end

#set_parent_ancestorsObject



42
43
44
# File 'app/models/com/ext/taxon.rb', line 42

def set_parent_ancestors
  self.parent_ancestors = Hash(parent.parent_ancestors).merge! parent.depth.to_s => parent.id
end

#sheer_ancestor_idsObject



71
72
73
74
75
76
77
78
# File 'app/models/com/ext/taxon.rb', line 71

def sheer_ancestor_ids
  node, node_ids = self, []
  until (node_ids + [self.id]).include?(node.parent_id)
    node_ids << node.parent_id
    node = node.parent
  end
  node_ids
end

#sheer_descendant_ids(c_ids = child_ids) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
# File 'app/models/com/ext/taxon.rb', line 59

def sheer_descendant_ids(c_ids = child_ids)
  @sheer_descendant_ids ||= c_ids.dup
  get_ids = self.class.where(parent_id: c_ids).pluck(:id)
  if get_ids.present?
    _get_ids = get_ids - @sheer_descendant_ids
    @sheer_descendant_ids.concat get_ids
    sheer_descendant_ids(_get_ids)
  else
    @sheer_descendant_ids
  end
end

#sync_parent_idObject



46
47
48
49
50
51
52
53
# File 'app/models/com/ext/taxon.rb', line 46

def sync_parent_id
  _parent_id = Hash(parent_ancestors).values.compact.last
  if _parent_id
    self.parent_id = _parent_id
  else
    self.parent_id = nil
  end
end