Class: StructuredParams::Params

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Attributes, ActiveModel::Model, AttributeMethods, I18n, Validations
Defined in:
lib/structured_params/params.rb

Overview

Parameter model that supports structured objects and arrays

This class can be used in two ways:

  1. Strong Parameters validation (API requests)

  2. Form objects (View integration with form_with/form_for)

Strong Parameters example (API):

class UserParams < StructuredParams::Params
  attribute :name, :string
  attribute :age, :integer
  attribute :address, :object, value_class: AddressParams
  attribute :hobbies, :array, value_class: HobbyParams
  attribute :tags, :array, value_type: :string

  # Validate raw input before type casting (e.g., "12x" for integer fields)
  validates_raw :age, format: { with: /\A\d+\z/, message: 'must be numeric string' }
end

# In controller:
user_params = UserParams.new(params)
if user_params.valid?
  User.create!(user_params.attributes)
else
  render json: { errors: user_params.errors }
end

Form object example (View integration):

class UserRegistrationForm < StructuredParams::Params
  attribute :name, :string
  attribute :email, :string
  validates :name, presence: true
  validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
end

# In controller:
@form = UserRegistrationForm.new(UserRegistrationForm.permit(params))
if @form.valid?
  User.create!(@form.attributes)
  redirect_to user_path
else
  render :new
end

# In view:
<%= form_with model: @form, url: users_path do |f| %>
  <%= f.text_field :name %>
  <%= f.text_field :email %>
<% end %>

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params) ⇒ Params

: (Hash[untyped, untyped]|::ActionController::Parameters) -> void



149
150
151
152
# File 'lib/structured_params/params.rb', line 149

def initialize(params)
  processed_params = process_input_parameters(params)
  super(**processed_params)
end

Class Method Details

.model_nameObject

Override model_name for form helpers By default, removes “Parameters”, “Parameter”, or “Form” suffix from class name This allows the class to work seamlessly with Rails form helpers

Example:

UserRegistrationForm.model_name.name       # => "UserRegistration"
UserRegistrationForm.model_name.param_key  # => "user_registration"
UserParameters.model_name.name             # => "User"
Admin::UserForm.model_name.name            # => "Admin::User"

: () -> ::ActiveModel::Name



76
77
78
79
80
81
82
83
# File 'lib/structured_params/params.rb', line 76

def model_name
  @model_name ||= begin
    namespace = module_parents.detect { |n| n.respond_to?(:use_relative_model_naming?) }
    # Remove suffix from the full class name (preserving namespace)
    name_without_suffix = name.sub(/(Parameters?|Form)$/, '')
    ActiveModel::Name.new(self, namespace, name_without_suffix)
  end
end

.permit(params, require: true) ⇒ Object

Permit parameters with optional require

For Form Objects (with require):

UserRegistrationForm.permit(params)
# equivalent to:
params.require(:user_registration).permit(*UserRegistrationForm.permit_attribute_names)

For API requests (without require):

UserParams.permit(params, require: false)
# equivalent to:
params.permit(*UserParams.permit_attribute_names)

: (ActionController::Parameters params, ?require: bool) -> ActionController::Parameters



112
113
114
115
116
117
118
119
# File 'lib/structured_params/params.rb', line 112

def permit(params, require: true)
  if require
    key = model_name.param_key.to_sym
    params.require(key).permit(*permit_attribute_names)
  else
    params.permit(*permit_attribute_names)
  end
end

.permit_attribute_namesObject

Generate permitted parameter structure for Strong Parameters : () -> Array



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/structured_params/params.rb', line 87

def permit_attribute_names
  attribute_types.map do |name, type|
    name = name.to_sym

    if type.is_a?(Type::Object) || type.is_a?(Type::Array)
      { name => type.permit_attribute_names }
    else
      name
    end
  end
end

.structured_attributesObject

Get structured attributes and their classes : () -> Hash[Symbol, singleton(::StructuredParams::Params)]



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/structured_params/params.rb', line 123

def structured_attributes
  @structured_attributes ||= attribute_types.each_with_object({}) do |(name, type), hash|
    next unless structured_params_type?(type)

    hash[name] = if type.is_a?(Type::Array)
                   type.item_type.value_class
                 else
                   type.value_class
                 end
  end
end

Instance Method Details

#attributes(symbolize: false, compact_mode: :none) ⇒ Object

Convert structured objects to Hash and get attributes : (?symbolize: false, ?compact_mode: :none | :nil_only | :all_blank) -> Hash[String, untyped] : (?symbolize: true, ?compact_mode: :none | :nil_only | :all_blank) -> Hash[Symbol, untyped]



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/structured_params/params.rb', line 188

def attributes(symbolize: false, compact_mode: :none)
  attrs = super()

  self.class.structured_attributes.each_key do |name|
    value = attrs[name.to_s]
    attrs[name.to_s] = serialize_structured_value(value, compact_mode: compact_mode)
  end

  result = symbolize ? attrs.deep_symbolize_keys : attrs

  case compact_mode
  when :all_blank
    result.compact_blank
  when :nil_only
    result.compact
  else
    result
  end
end

#errorsObject

: () -> ::StructuredParams::Errors



155
156
157
# File 'lib/structured_params/params.rb', line 155

def errors
  @errors ||= Errors.new(self)
end

#persisted?Boolean

Indicates whether the form object has been persisted to database Always returns false for parameter/form objects : () -> bool

Returns:

  • (Boolean)


167
168
169
# File 'lib/structured_params/params.rb', line 167

def persisted?
  false
end

#to_keyObject

Returns the primary key value for the model Always returns nil for parameter/form objects : () -> nil



174
175
176
# File 'lib/structured_params/params.rb', line 174

def to_key
  nil
end

#to_modelObject

Returns self for form helpers Required by Rails form helpers to get the model object : () -> self



181
182
183
# File 'lib/structured_params/params.rb', line 181

def to_model
  self
end