Class: ActiveRecord::Base

Inherits:
Object show all
Defined in:
lib/brick/extensions.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

._assoc_namesObject



62
63
64
# File 'lib/brick/extensions.rb', line 62

def self._assoc_names
  @_assoc_names ||= {}
end

._br_associativesObject

has_many :through associative tables



234
235
236
# File 'lib/brick/extensions.rb', line 234

def _br_associatives
  @_br_associatives ||= {}
end

._br_bt_descripObject

belongs_to DSL descriptions



226
227
228
# File 'lib/brick/extensions.rb', line 226

def _br_bt_descrip
  @_br_bt_descrip ||= {}
end

._br_hm_countsObject

has_many count definitions



230
231
232
# File 'lib/brick/extensions.rb', line 230

def _br_hm_counts
  @_br_hm_counts ||= {}
end

._brick_calculate_bts_hms(translations, join_array) ⇒ Object

Search for BT, HM, and HMT DSL stuff



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/brick/extensions.rb', line 240

def self._brick_calculate_bts_hms(translations, join_array)
  bts, hms, associatives = ::Brick.get_bts_and_hms(self)
  bts.each do |_k, bt|
    next if bt[2] # Polymorphic?

    # join_array will receive this relation name when calling #brick_parse_dsl
    _br_bt_descrip[bt.first] = if bt[1].is_a?(Array)
                                 bt[1].each_with_object({}) { |bt_class, s| s[bt_class] = bt_class.brick_parse_dsl(join_array, bt.first, translations, true) }
                               else
                                 { bt.last => bt[1].brick_parse_dsl(join_array, bt.first, translations) }
                               end
  end
  skip_klass_hms = ::Brick.config.skip_index_hms[self.name] || {}
  hms.each do |k, hm|
    next if skip_klass_hms.key?(k)

    if hm.macro == :has_one
      # For our purposes a :has_one is similar enough to a :belongs_to that we can just join forces
      _br_bt_descrip[k] = { hm.klass => hm.klass.brick_parse_dsl(join_array, k, translations) }
    else # Standard :has_many
      _br_hm_counts[k] = hm unless hm.options[:through] && !_br_associatives.fetch(hm.name, nil)
    end
  end
end

._brick_calculate_ordering(ordering, is_do_txt = true) ⇒ Object



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/brick/extensions.rb', line 265

def self._brick_calculate_ordering(ordering, is_do_txt = true)
  quoted_table_name = table_name.split('.').map { |x| "\"#{x}\"" }.join('.')
  order_by_txt = [] if is_do_txt
  ordering = [ordering] if ordering && !ordering.is_a?(Array)
  order_by = ordering&.map do |ord_part| # %%% If a term is also used as an eqi-condition in the WHERE clause, it can be omitted from ORDER BY
               case ord_part
               when String
                 ord_expr = ord_part.gsub('^^^', quoted_table_name)
                 order_by_txt&.<<("Arel.sql(#{ord_expr})")
                 Arel.sql(ord_expr)
               else # Expecting only Symbol
                 ord_part = "_br_#{ord_part}_ct" if _br_hm_counts.key?(ord_part)
                 # Retain any reference to a bt_descrip as being a symbol
                 # Was:  "#{quoted_table_name}.\"#{ord_part}\""
                 order_by_txt&.<<(_br_bt_descrip.key?(ord_part) ? ord_part : ord_part.inspect)
                 ord_part
               end
             end
  [order_by, order_by_txt]
end

._brick_primary_key(relation = nil) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/brick/extensions.rb', line 70

def self._brick_primary_key(relation = nil)
  return instance_variable_get(:@_brick_primary_key) if instance_variable_defined?(:@_brick_primary_key)

  pk = begin
         primary_key.is_a?(String) ? [primary_key] : primary_key || []
       rescue
         []
       end
  # Just return [] if we're missing any part of the primary key.  (PK is usually just "id")
  if relation && pk.present?
    @_brick_primary_key ||= pk.any? { |pk_part| !relation[:cols].key?(pk_part) } ? [] : pk
  else # No definitive key yet, so return what we can without setting the instance variable
    pk
  end
end

.brick_descrip(obj, data = nil, pk_alias = nil) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
# File 'lib/brick/extensions.rb', line 152

def self.brick_descrip(obj, data = nil, pk_alias = nil)
  if (dsl = ::Brick.config.model_descrips[(klass = self).name] || klass.brick_get_dsl)
    idx = -1
    caches = {}
    output = +''
    is_brackets_have_content = false
    bracket_name = nil
    dsl.each_char do |ch|
      if bracket_name
        if ch == ']' # Time to process a bracketed thing?
          datum = if data
                    data[idx += 1].to_s
                  else
                    obj_name = +''
                    this_obj = obj
                    bracket_name.split('.').each do |part|
                      obj_name += ".#{part}"
                      this_obj = caches.fetch(obj_name) { caches[obj_name] = this_obj&.send(part.to_sym) }
                      break if this_obj.nil?
                    end
                    this_obj&.to_s || ''
                  end
          is_brackets_have_content = true unless (datum).blank?
          output << (datum || '')
          bracket_name = nil
        else
          bracket_name << ch
        end
      elsif ch == '['
        bracket_name = +''
      else
        output << ch
      end
    end
    output += bracket_name if bracket_name
  end
  if is_brackets_have_content
    output
  elsif (pk_alias ||= primary_key)
    pk_alias = [pk_alias] unless pk_alias.is_a?(Array)
    id = []
    pk_alias.each do |pk_alias_part|
      if (pk_part = obj.send(pk_alias_part))
        id << pk_part
      end
    end
    if id.present?
      "#{klass.name} ##{id.join(', ')}"
    end
  else
    obj.to_s
  end
end

.brick_get_dslObject

Used to show a little prettier name for an object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/brick/extensions.rb', line 87

def self.brick_get_dsl
  # If there's no DSL yet specified, just try to find the first usable column on this model
  unless (dsl = ::Brick.config.model_descrips[name])
    descrip_col = (columns.map(&:name) - _brick_get_fks -
                  (::Brick.config. || []) -
                  [primary_key]).first
    dsl = ::Brick.config.model_descrips[name] = if descrip_col
                                                  "[#{descrip_col}]"
                                                elsif (pk_parts = self.primary_key.is_a?(Array) ? self.primary_key : [self.primary_key])
                                                  "#{name} ##{pk_parts.map { |pk_part| "[#{pk_part}]" }.join(', ')}"
                                                end
  end
  dsl
end

.brick_import_templateObject



216
217
218
219
220
221
222
# File 'lib/brick/extensions.rb', line 216

def self.brick_import_template
  template = constants.include?(:IMPORT_TEMPLATE) ? self::IMPORT_TEMPLATE : suggest_template(false, false, 0)
  # Add the primary key to the template as being unique (unless it's already there)
  template[:uniques] = [pk = primary_key.to_sym]
  template[:all].unshift(pk) unless template[:all].include?(pk)
  template
end

.brick_parse_dsl(build_array = nil, prefix = [], translations = {}, is_polymorphic = false) ⇒ Object



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
# File 'lib/brick/extensions.rb', line 102

def self.brick_parse_dsl(build_array = nil, prefix = [], translations = {}, is_polymorphic = false)
  build_array = ::Brick::JoinArray.new.tap { |ary| ary.replace([build_array]) } if build_array.is_a?(::Brick::JoinHash)
  build_array = ::Brick::JoinArray.new unless build_array.nil? || build_array.is_a?(Array)
  members = []
  bracket_name = nil
  prefix = [prefix] unless prefix.is_a?(Array)
  if (dsl = ::Brick.config.model_descrips[name] || brick_get_dsl)
    klass = nil
    dsl.each_char do |ch|
      if bracket_name
        if ch == ']' # Time to process a bracketed thing?
          parts = bracket_name.split('.')
          first_parts = parts[0..-2].map do |part|
            klass = (orig_class = klass).reflect_on_association(part_sym = part.to_sym)&.klass
            puts "Couldn't reference #{orig_class.name}##{part} that's part of the DSL \"#{dsl}\"." if klass.nil?
            part_sym
          end
          parts = prefix + first_parts + [parts[-1]]
          if parts.length > 1
            unless is_polymorphic
              s = build_array
              parts[0..-3].each { |v| s = s[v.to_sym] }
              s[parts[-2]] = nil # unless parts[-2].empty? # Using []= will "hydrate" any missing part(s) in our whole series
            end
            translations[parts[0..-2].join('.')] = klass
          end
          members << parts
          bracket_name = nil
        else
          bracket_name << ch
        end
      elsif ch == '['
        bracket_name = +''
        klass = self
      end
    end
  else # With no DSL available, still put this prefix into the JoinArray so we can get primary key (ID) info from this table
    x = prefix.each_with_object(build_array) { |v, s| s[v.to_sym] }
    x[prefix.last] = nil unless prefix.empty? # Using []= will "hydrate" any missing part(s) in our whole series
  end
  members
end


206
207
208
209
210
211
212
213
214
# File 'lib/brick/extensions.rb', line 206

def self.bt_link(assoc_name)
  model_underscore = name.underscore
  assoc_name = CGI.escapeHTML(assoc_name.to_s)
  model_path = Rails.application.routes.url_helpers.send("#{model_underscore.tr('/', '_').pluralize}_path".to_sym)
  av_class = Class.new.extend(ActionView::Helpers::UrlHelper)
  av_class.extend(ActionView::Helpers::TagHelper) if ActionView.version < ::Gem::Version.new('7')
  link = av_class.link_to(name, model_path)
  model_underscore == assoc_name ? link : "#{assoc_name}-#{link}".html_safe
end

.is_view?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/brick/extensions.rb', line 66

def self.is_view?
  false
end

Instance Method Details

#brick_descrip(data = nil, pk_alias = nil) ⇒ Object

If available, parse simple DSL attached to a model in order to provide a friendlier name. Object property names can be referenced in square brackets like this: { ‘User’ => ‘[profile.firstname] [profile.lastname]’ }



148
149
150
# File 'lib/brick/extensions.rb', line 148

def brick_descrip(data = nil, pk_alias = nil)
  self.class.brick_descrip(self, data, pk_alias)
end