Module: Referehencible::ClassMethods

Defined in:
lib/referehencible.rb

Overview

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength

Instance Method Summary collapse

Instance Method Details

#referenced_by(*referenced_attrs) ⇒ Object



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
37
38
39
40
41
42
43
44
45
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
# File 'lib/referehencible.rb', line 9

def referenced_by(*referenced_attrs)
  default_options = {
    length: DEFAULT_LENGTH,
    type:   :uuid,
  }

  referenced_attrs = \
    referenced_attrs.each_with_object({}) do |referenced_attr, transformed_attr|
      case referenced_attr
      when Symbol
        transformed_attr[referenced_attr] = default_options
      when Hash
        transformed_attr.merge! referenced_attr
      end
    end

  referenced_attrs.each do |reference_attribute, options|
    fail "You attempted to pass in a length of #{options[:length]} for " \
         "#{reference_attribute} in #{name}. Only even numbers are allowed." \
      if options[:length].odd?

    validates reference_attribute,
              presence:   true,
              uniqueness: true,
              format:     {
                with:             /[a-f0-9\-]{#{options[:length]}}/ },
              length:     {
                is:               options[:length] }

    define_method(reference_attribute) do
      send("generate_#{options[:type]}_guid",
           reference_attribute,
           options[:length] / 2)
    end

    define_singleton_method("by_#{reference_attribute}") do |guid_to_find|
      where(:"#{reference_attribute}" => guid_to_find).
        first ||
        unknown_reference_object
    end

    after_initialize lambda do
      send("generate_#{options[:type]}_guid",
           reference_attribute,
           options[:length] / 2)
    end
  end

  private

  define_method(:generate_hex_guid) do |reference_attribute, length|
    read_attribute(reference_attribute) || write_attribute(reference_attribute,
                                                           SecureRandom.hex(length))
  end

  define_method(:generate_uuid_guid) do |reference_attribute, _length|
    read_attribute(reference_attribute) || write_attribute(reference_attribute,
                                                           SecureRandom.uuid)
  end

  define_singleton_method(:unknown_reference_object) do
    return new unless respond_to?(:as_null_object)

    as_null_object
  end
end