Module: Card::Set::All::References

Extended by:
Card::Set
Defined in:
tmpsets/set/mod003-core/all/references.rb

Overview

Cards can refer to other cards in their content, eg via links and nests.

Constant Summary collapse

PARTIAL_REF_CODE =

which handles id-based reference tracking.

"P".freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from I18nScope

#mod_name, #scope

Methods included from Loader

#clean_empty_module_from_hash, #clean_empty_modules, #extended, #process_base_modules, #register_set

Methods included from Helpers

#abstract_set?, #all_set?, #num_set_parts, #shortname, #underscore

Methods included from Card::Set::AdvancedApi

#attachment, #ensure_set, #stage_method

Methods included from Format

#before, #format, layout_method_name, #view, view_method_name, view_setting_method_name, wrapper_method_name

Methods included from Inheritance

#include_set, #include_set_formats

Methods included from Basket

#abstract_basket, #add_to_basket, #basket, #unshift_basket

Methods included from Trait

#card_accessor, #card_reader, #card_writer, #require_field

Methods included from Event::Api

#event

Class Method Details

.source_locationObject



10
# File 'tmpsets/set/mod003-core/all/references.rb', line 10

def self.source_location; "/Users/ethan/dev/decko/gem/card/mod/core/set/all/references.rb"; end

Instance Method Details

#create_references_outObject

interpret references from this card's content and insert entries in reference table



79
80
81
82
83
84
85
86
# File 'tmpsets/set/mod003-core/all/references.rb', line 79

def create_references_out
  ref_hash = {}
  each_reference_out do |referee_name, ref_type|
    interpret_reference ref_hash, referee_name, ref_type
  end
  return if ref_hash.empty?
  Card::Reference.mass_insert reference_values_array(ref_hash)
end

#delete_references_outObject

delete references from this card



89
90
91
92
# File 'tmpsets/set/mod003-core/all/references.rb', line 89

def delete_references_out
  raise "id required to delete references" if id.nil?
  Card::Reference.where(referer_id: id).delete_all
end

#each_reference_outObject

invokes the given block for each reference in content with the reference name and reference type



139
140
141
142
143
144
# File 'tmpsets/set/mod003-core/all/references.rb', line 139

def each_reference_out
  content_obj = Card::Content.new content, self
  content_obj.find_chunks(Card::Content::Chunk::Reference).each do |chunk|
    yield(chunk.referee_name, chunk.reference_code)
  end
end

#family_referersObject

cards that refer to self or any descendant



52
53
54
55
# File 'tmpsets/set/mod003-core/all/references.rb', line 52

def family_referers
  @family_referers ||= ([self] + descendants).map(&:referers).flatten.uniq
  # TODO: make this more efficient using partial references!
end

#interpret_partial_references(ref_hash, referee_name) ⇒ Object

Partial references are needed to track references to virtual cards. For example a link to virual card [[A+*self]] won't have a referee_id, but when A's name is changed we have to find and update that link.



115
116
117
118
119
# File 'tmpsets/set/mod003-core/all/references.rb', line 115

def interpret_partial_references ref_hash, referee_name
  [referee_name.left, referee_name.right].each do |sidename|
    interpret_reference ref_hash, sidename, PARTIAL_REF_CODE
  end
end

#interpret_reference(ref_hash, referee_name, ref_type) ⇒ Object

interpretation phase helps to prevent duplicate references results in hash like: { referee1_key: [referee1_id, referee1_type1, referee1_type2], referee2_key... }



99
100
101
102
103
104
105
106
107
108
109
110
# File 'tmpsets/set/mod003-core/all/references.rb', line 99

def interpret_reference ref_hash, referee_name, ref_type
  return unless referee_name # eg commented nest has no referee_name
  referee_name = referee_name.to_name
  referee_key = referee_name.key
  return if referee_key == key # don't create self reference

  referee_id = Card.fetch_id(referee_name)
  ref_hash[referee_key] ||= [referee_id]
  ref_hash[referee_key] << ref_type

  interpret_partial_references ref_hash, referee_name unless referee_id
end

#name_referersObject

cards that refer to self by name (finds cards not yet linked by id)



47
48
49
# File 'tmpsets/set/mod003-core/all/references.rb', line 47

def name_referers
  Card.joins(:references_out).where card_references: { referee_key: key }
end

#nesteesObject

cards that self includes



37
38
39
# File 'tmpsets/set/mod003-core/all/references.rb', line 37

def nestees
  referees_from_references references_out.where(ref_type: "I")
end

#nestersObject

cards that include self



23
24
25
# File 'tmpsets/set/mod003-core/all/references.rb', line 23

def nesters
  referer_cards_from_references references_in.where(ref_type: "I")
end

#refereesObject

cards that self refers to



32
33
34
# File 'tmpsets/set/mod003-core/all/references.rb', line 32

def referees
  referees_from_references references_out
end

#referees_from_references(references) ⇒ Object



41
42
43
# File 'tmpsets/set/mod003-core/all/references.rb', line 41

def referees_from_references references
  references.map(&:referee_key).uniq.map { |key| Card.fetch key, new: {} }
end

#reference_values_array(ref_hash) ⇒ Object

translate interpreted reference hash into values array, removing duplicate and unnecessary ref_types



123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'tmpsets/set/mod003-core/all/references.rb', line 123

def reference_values_array ref_hash
  values = []
  ref_hash.each do |referee_key, hash_val|
    referee_id = hash_val.shift || "null"
    ref_types = hash_val.uniq
    ref_types.delete PARTIAL_REF_CODE if ref_types.size > 1
    # partial references are not necessary if there are explicit references
    ref_types.each do |ref_type|
      values << [id, referee_id, "'#{referee_key}'", "'#{ref_type}'"]
    end
  end
  values
end

#referer_cards_from_references(references) ⇒ Object



27
28
29
# File 'tmpsets/set/mod003-core/all/references.rb', line 27

def referer_cards_from_references references
  references.map(&:referer_id).uniq.map(&Card.method(:fetch)).compact
end

#referersObject

cards that refer to self



18
19
20
# File 'tmpsets/set/mod003-core/all/references.rb', line 18

def referers
  referer_cards_from_references references_in
end

#replace_reference_syntax(old_name, new_name) ⇒ Object

replace references in card content



58
59
60
61
62
63
64
65
66
67
68
69
# File 'tmpsets/set/mod003-core/all/references.rb', line 58

def replace_reference_syntax old_name, new_name
  obj_content = Card::Content.new content, self
  obj_content.find_chunks(Card::Content::Chunk::Reference).select do |chunk|
    next unless (old_ref_name = chunk.referee_name)
    next unless (new_ref_name = old_ref_name.swap old_name, new_name)
    chunk.referee_name = chunk.replace_reference old_name, new_name
    refs = Card::Reference.where referee_key: old_ref_name.key
    refs.update_all referee_key: new_ref_name.key
  end

  obj_content.to_s
end

#update_references_outObject

delete old references from this card's content, create new ones



72
73
74
75
# File 'tmpsets/set/mod003-core/all/references.rb', line 72

def update_references_out
  delete_references_out
  create_references_out
end