Attributes API allows you to have complex object with specified structure in fields. But how to make forms with this fields?
The answer is pretty simple: you work with them like with nested attributes.
Let’s say, we have class Provider with attribute address.
class Provider < ApplicationRecord attribute :address, Provider::Address::Type.new, default: Provider::Address.new
Address has following attributes:
class Provider::Address extend Dry::Initializer option :country, optional: true option :zip, optional: true option :city, optional: true option :address, optional: true
Form will look like this:
= form_for resource_provider, provider_url do |f| = f.fields_for :address do |ff| = ff.label 'Country' = ff.text_field :country, value: @provider.billing_address.country = ff.label 'Zip' = ff.text_field :zip, value: @provider.billing_address.zip = ff.label 'City' = ff.text_field :city, value: @provider.billing_address.city = ff.label 'Address' = ff.text_field :address, value: @provider.billing_address.address
In controller you have to permit parameters:
def provider_params params.require(:provider).permit(address: [:city, :zip, :country, :address]) end
And that’s all. Now, in action method you can assign attributes like this:
resource_provider.attributes = provider_params resource_provider.save