Class: Expressir::Model::ModelElement

Inherits:
Object
  • Object
show all
Defined in:
lib/expressir/model/model_element.rb

Overview

Base model element

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ ModelElement

Returns a new instance of ModelElement.

Parameters:

  • options (Hash) (defaults to: {})


19
20
21
# File 'lib/expressir/model/model_element.rb', line 19

def initialize(options = {})
  attach_parent_to_children
end

Instance Attribute Details

#parentModelElement

Returns:



16
17
18
# File 'lib/expressir/model/model_element.rb', line 16

def parent
  @parent
end

Class Method Details

.from_hash(hash, root_path: nil) ⇒ ModelElement

Parameters:

  • hash (Hash)
  • root_path (String) (defaults to: nil)

Returns:



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/expressir/model/model_element.rb', line 176

def self.from_hash(hash, root_path: nil)
  node_class = Object.const_get(hash[CLASS_KEY])
  node_options = {}

  node_class.model_attrs.each do |variable|
    value = hash[variable.to_s]

    node_options[variable] = case value
    when Array
      value.map do |value|
        if value.is_a? Hash
          self.from_hash(value, root_path: root_path)
        else
          value
        end
      end
    when Hash
      self.from_hash(value, root_path: root_path)
    else
      value
    end
  end

  if node_class == Declarations::Schema and hash[FILE_KEY]
    node_options[FILE_KEY.to_sym] = root_path ? File.expand_path("#{root_path}/#{hash[FILE_KEY]}") : hash[FILE_KEY]
  end

  node = node_class.new(node_options)

  node
end

.model_attr_accessor(attr_name, attr_type = nil) ⇒ Object

Define a new model attribute

Parameters:

  • attr_name (Symbol)

    attribute name

  • attr_type (Symbol) (defaults to: nil)

    attribute type



219
220
221
222
223
224
# File 'lib/expressir/model/model_element.rb', line 219

def self.model_attr_accessor(attr_name, attr_type = nil)
  @model_attrs ||= []
  @model_attrs << attr_name

  attr_accessor attr_name
end

.model_attrsArray<Symbol>

Returns:

  • (Array<Symbol>)


209
210
211
# File 'lib/expressir/model/model_element.rb', line 209

def self.model_attrs
  @model_attrs ||= []
end

Instance Method Details

#childrenArray<Declaration>

Returns:



79
80
81
# File 'lib/expressir/model/model_element.rb', line 79

def children
  []
end

#children_by_idHash<String, Declaration>

Returns:



84
85
86
# File 'lib/expressir/model/model_element.rb', line 84

def children_by_id
  @children_by_id ||= children.select{|x| x.id}.map{|x| [x.id.safe_downcase, x]}.to_h
end

#find(path) ⇒ ModelElement

Parameters:

Returns:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/expressir/model/model_element.rb', line 46

def find(path)
  return self if path.empty?

  path_parts = path.safe_downcase.split(/\./).map do |current_path|
    _, _, current_path = current_path.rpartition(":") # ignore prefix
    current_path
  end

  current_scope = self
  target_node = nil
  loop do
    # find in current scope
    current_node = current_scope
    path_parts.each do |current_path|
      current_node = current_node.children_by_id[current_path]
      break unless current_node
    end
    target_node = current_node
    break if target_node

    # retry search in parent scope
    current_scope = current_scope.parent
    break unless current_scope
  end

  if target_node.is_a? Model::Declarations::InterfacedItem
    target_node = target_node.base_item
  end

  target_node
end

#pathString

Returns:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/expressir/model/model_element.rb', line 24

def path
  # this creates an implicit scope
  return if is_a? Statements::Alias or is_a? Statements::Repeat or is_a? Expressions::QueryExpression

  current_node = self
  path_parts = []
  loop do
    if current_node.class.method_defined? :id and !(current_node.is_a? References::SimpleReference)
      path_parts << current_node.id
    end

    current_node = current_node.parent
    break unless current_node
  end

  return if path_parts.empty?

  path_parts.reverse.join(".")
end

#reset_children_by_idnil

Returns:

  • (nil)


89
90
91
92
# File 'lib/expressir/model/model_element.rb', line 89

def reset_children_by_id
  @children_by_id = nil
  nil
end

#to_hash(root_path: nil, formatter: nil, include_empty: nil, select_proc: nil) ⇒ Hash

Parameters:

  • root_path (String) (defaults to: nil)
  • formatter (Express::Formatter) (defaults to: nil)
  • include_empty (Boolean) (defaults to: nil)
  • select_proc (Proc) (defaults to: nil)

Returns:

  • (Hash)


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/expressir/model/model_element.rb', line 99

def to_hash(root_path: nil, formatter: nil, include_empty: nil, select_proc: nil)
  # Filter out entries
  has_filter = !select_proc.nil? && select_proc.is_a?(Proc)
  return nil if has_filter && !select_proc.call(self)

  hash = {}
  hash[CLASS_KEY] = self.class.name

  self.class.model_attrs.each do |variable|
    value = self.send(variable)
    empty = value.nil? || (value.is_a?(Array) && value.count == 0)

    # skip empty values
    next unless !empty or include_empty

    value_hash = case value
                 when Array
                   value.map do |v|
                     if v.is_a? ModelElement
                       v.to_hash(
                         root_path: root_path,
                         formatter: formatter,
                         include_empty: include_empty,
                         select_proc: select_proc
                       )
                     else
                       v
                     end
                   end.compact
                 when ModelElement
                   value.to_hash(
                     root_path: root_path,
                     formatter: formatter,
                     include_empty: include_empty,
                     select_proc: select_proc
                   )
                 else
                   value
                 end

    hash[variable.to_s] = value_hash unless value_hash.nil?
  end

  if self.is_a? Declarations::Schema and file
    hash[FILE_KEY] = root_path ? Pathname.new(file).relative_path_from(root_path).to_s : file
  end

  if self.class.method_defined? :source and formatter
    hash[SOURCE_KEY] = formatter.format(self)
  end

  hash
end

#to_liquidLiquid::Drop

Returns:

  • (Liquid::Drop)


154
155
156
157
158
# File 'lib/expressir/model/model_element.rb', line 154

def to_liquid
  klass_name = self.class.name.gsub("::Model::", "::Liquid::") + "Drop"
  klass = Object.const_get(klass_name)
  klass.new(self)
end

#to_s(no_remarks: false, formatter: nil) ⇒ Object



160
161
162
# File 'lib/expressir/model/model_element.rb', line 160

def to_s
  to_s(no_remarks: false, formatter: nil)
end