Module: ActiveFields::CustomizableConcern

Extended by:
ActiveSupport::Concern
Defined in:
app/models/concerns/active_fields/customizable_concern.rb

Overview

Model mix-in that adds the active fields functionality to the customizable model

Instance Method Summary collapse

Instance Method Details

#active_fieldsObject



21
22
23
# File 'app/models/concerns/active_fields/customizable_concern.rb', line 21

def active_fields
  ActiveFields.config.field_base_class.for(model_name.name)
end

#active_fields_attributes=(attributes) ⇒ Object Also known as: active_fields=

Assigns the given attributes to the active_values association.

Accepts an Array of Hashes (symbol/string keys) or permitted params. Each element should contain a :name key matching an existing active_field record. Element with a :value key will create an active_value if it doesn’t exist or update an existing active_value, with the provided value. Element with a :_destroy key set to a truthy value will mark the matched active_value for destruction.

Example:

customizable.active_fields_attributes = [
  { name: "integer_array", value: [1, 4, 5, 5, 0] }, # create or update (symbol keys)
  { "name" => "text", "value" => "Lasso" }, # create or update (string keys)
  { name: "date", _destroy: true }, # destroy (symbol keys)
  { "name" => "boolean", "_destroy" => true }, # destroy (string keys)
  permitted_params, # params could be passed, but they must be permitted
]


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
# File 'app/models/concerns/active_fields/customizable_concern.rb', line 43

def active_fields_attributes=(attributes)
  attributes = attributes.to_h if attributes.respond_to?(:permitted?)

  unless attributes.is_a?(Array) || attributes.is_a?(Hash)
    raise ArgumentError, "Array or Hash expected for `active_fields=`, got #{attributes.class.name}"
  end

  # Handle `fields_for` params
  attributes = attributes.values if attributes.is_a?(Hash)

  active_fields_by_name = active_fields.index_by(&:name)
  active_values_by_field_id = active_values.index_by(&:active_field_id)

  nested_attributes = attributes.filter_map do |active_value_attributes|
    # Convert params to Hash
    active_value_attributes = active_value_attributes.to_h if active_value_attributes.respond_to?(:permitted?)
    active_value_attributes = active_value_attributes.with_indifferent_access

    active_field = active_fields_by_name[active_value_attributes[:name]]
    next if active_field.nil?

    active_value = active_values_by_field_id[active_field.id]

    if has_destroy_flag?(active_value_attributes)
      # Destroy
      { id: active_value&.id, _destroy: true }
    elsif active_value
      # Update
      { id: active_value.id, value: active_value_attributes[:value] }
    else
      # Create
      { active_field: active_field, value: active_value_attributes[:value] }
    end
  end

  self.active_values_attributes = nested_attributes
end

#initialize_active_valuesObject

Build an active_value, if it doesn’t exist, with a default value for each available active_field. Returns active_values collection.



85
86
87
88
89
90
91
92
93
94
95
# File 'app/models/concerns/active_fields/customizable_concern.rb', line 85

def initialize_active_values
  existing_field_ids = active_values.map(&:active_field_id)

  active_fields.each do |active_field|
    next if existing_field_ids.include?(active_field.id)

    active_values.new(active_field: active_field, value: active_field.default_value)
  end

  active_values
end