aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/concerns/custom_fields_support.rb
blob: f55ff923bff6f44ec4b82faa9dd886abd435c2bc (plain)
1
2
3
4
5
6
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
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
75
76
77
78
79
80
81
module CustomFieldsSupport
  extend ActiveSupport::Concern

  included do
    validate :custom_fields_values_are_valid
    after_initialize :initialize_custom_fields

    def self.custom_fields workgroup
      return CustomField.none unless workgroup
      fields = CustomField.where(resource_type: self.name.split("::").last)
      fields = fields.where(workgroup_id: workgroup.id)
      fields
    end

    def self.custom_fields_definitions workgroup
      Hash[*custom_fields(workgroup).map{|cf| [cf.code, cf]}.flatten]
    end

    def method_missing method_name, *args
      if !@custom_fields_initialized && method_name =~ /custom_field_*/ && method_name.to_sym != :custom_field_values
        initialize_custom_fields
        send method_name, *args
      else
        super method_name, *args
      end
    end

    def custom_fields deprecated_workgroup=nil
      _workgroup = deprecated_workgroup || self.workgroup
      CustomField::Collection.new self, _workgroup
    end

    def custom_fields_checksum
      custom_fields.values.sort_by(&:code).map(&:checksum)
    end

    def custom_field_values= vals
      if custom_fields_initialized?
        out = {}
        custom_fields.each do |code, field|
          out[code] = field.preprocess_value_for_assignment(vals.symbolize_keys[code.to_sym])
        end
        @custom_fields_values_initialized = true
      else
        @raw_custom_fields_values = vals
        out = vals
      end
      write_attribute :custom_field_values, out
    end

    def custom_fields_initialized?
      !!@custom_fields_initialized
    end

    def custom_fields_values_initialized?
      !!@custom_fields_values_initialized
    end

    def initialize_custom_fields
      return if custom_fields_initialized?
      return unless self.attributes.has_key?("custom_field_values")
      return unless self.workgroup.present?
      self.custom_field_values ||= {}
      custom_fields.values.each &:initialize_custom_field
      custom_fields.each do |k, v|
        custom_field_values[k] ||= v.default_value
      end
      @custom_fields_initialized = true
      self.custom_field_values = (@raw_custom_fields_values || self.custom_field_values) unless custom_fields_values_initialized?
    end

    def custom_field_value key
      (custom_field_values&.stringify_keys || {})[key.to_s]
    end

    private
    def custom_fields_values_are_valid
      custom_fields.values.all?{|cf| cf.valid?}
    end
  end
end