Class: StructuredParams::Type::Array

Inherits:
ActiveModel::Type::Value
  • Object
show all
Defined in:
lib/structured_params/type/array.rb,
sig/structured_params/type/array.rbs

Overview

Custom type for arrays of both StructuredParams::Params objects and primitive types

Usage examples:

# Array of nested objects
attribute :hobbies, :array, value_class: HobbyParameter

# Array of primitive types
attribute :tags, :array, value_type: :string

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value_class: nil, value_type: nil, **options) ⇒ Array

value_class or value_type is required : (?value_class: singleton(StructuredParams::Params)?, ?value_type: Symbol?, **untyped) -> void

Parameters:



19
20
21
22
23
# File 'lib/structured_params/type/array.rb', line 19

def initialize(value_class: nil, value_type: nil, **options)
  super()
  validate_parameters!(value_class, value_type)
  @item_type = build_item_type(value_class, value_type, options)
end

Instance Attribute Details

#item_typeActiveModel::Type::Value (readonly)

: ActiveModel::Type::Value

Returns:

  • (ActiveModel::Type::Value)


15
16
17
# File 'lib/structured_params/type/array.rb', line 15

def item_type
  @item_type
end

Instance Method Details

#build_item_type(value_class, value_type, options) ⇒ ActiveModel::Type::Value

Build item type : (singleton(StructuredParams::Params)?, Symbol?, Hash[untyped, untyped]) -> ActiveModel::Type::Value

Parameters:

Returns:

  • (ActiveModel::Type::Value)


101
102
103
104
105
106
107
# File 'lib/structured_params/type/array.rb', line 101

def build_item_type(value_class, value_type, options)
  if value_class
    StructuredParams::Type::Object.new(value_class: value_class)
  else
    ActiveModel::Type.lookup(value_type, **options)
  end
end

#cast(value) ⇒ ::Array[untyped]?

Cast value to array and convert each element to appropriate type : (untyped) -> ::Array?

Parameters:

Returns:

  • (::Array[untyped], nil)


32
33
34
35
36
# File 'lib/structured_params/type/array.rb', line 32

def cast(value)
  return nil if value.nil?

  ensure_array(value).map { |item| cast_item(item) }
end

#cast_item(item) ⇒ Object

Cast single item (delegate to new method) : (untyped) -> untyped

Parameters:

Returns:



79
80
81
82
83
84
85
# File 'lib/structured_params/type/array.rb', line 79

def cast_item(item)
  if item_type_is_structured_params_object?
    @item_type.value_class.new(item)
  else
    @item_type.cast(item)
  end
end

#ensure_array(value) ⇒ ::Array[untyped]

Convert value to array : (untyped) -> ::Array

Parameters:

Returns:

  • (::Array[untyped])


111
112
113
# File 'lib/structured_params/type/array.rb', line 111

def ensure_array(value)
  value.is_a?(::Array) ? value : [value]
end

#item_type_is_structured_params_object?Boolean

Determine if item type is StructuredParams::Object : () -> bool

Returns:

  • (Boolean)


71
72
73
# File 'lib/structured_params/type/array.rb', line 71

def item_type_is_structured_params_object?
  @item_type.is_a?(StructuredParams::Type::Object)
end

#permit_attribute_names::Array[untyped]

Get permitted parameter names for use with Strong Parameters

Returns:

- For object arrays (value_class): nested keys from the object
Example: HobbyParams with [:name, :level]
→ returns [:name, :level]
→ becomes { hobbies: [:name, :level] } in Params#permit_attribute_names

- For primitive arrays (value_type): empty array
Example: attribute :tags, :array, value_type: :string
→ returns []
→ becomes { tags: [] } in Params#permit_attribute_names
→ finally used as params.permit(:name, { tags: [] })

: () -> ::Array

Returns:

  • (::Array[untyped])


62
63
64
65
66
67
# File 'lib/structured_params/type/array.rb', line 62

def permit_attribute_names
  return @item_type.permit_attribute_names if item_type_is_structured_params_object?

  # Primitive arrays return [] for Strong Parameters format
  []
end

#serialize(value) ⇒ ::Array[untyped]?

Serialize array (convert each element to Hash) : (::Array?) -> ::Array?

Parameters:

  • (::Array[untyped], nil)

Returns:

  • (::Array[untyped], nil)


40
41
42
43
44
45
# File 'lib/structured_params/type/array.rb', line 40

def serialize(value)
  return nil if value.nil?
  return [] unless value.is_a?(::Array)

  value.map { |item| @item_type.serialize(item) }
end

#typeSymbol

: () -> Symbol

Returns:

  • (Symbol)


26
27
28
# File 'lib/structured_params/type/array.rb', line 26

def type
  :array
end

#validate_parameters!(value_class, value_type) ⇒ void

This method returns an undefined value.

Parameter validation : (singleton(StructuredParams::Params)?, Symbol?) -> void

Parameters:



89
90
91
92
93
94
95
96
97
# File 'lib/structured_params/type/array.rb', line 89

def validate_parameters!(value_class, value_type)
  if value_class && value_type
    raise ArgumentError, 'Specify either value_class or value_type, not both'
  elsif !value_class && !value_type
    raise ArgumentError, 'Either value_class or value_type must be specified'
  elsif value_class && !(value_class <= StructuredParams::Params)
    raise ArgumentError, "value_class must inherit from StructuredParams::Params, got #{value_class}"
  end
end