I am using Reform gem to make a form object for checkout in my web store. I have the Checkout form which contains properties for Order model, which has associations with Address model.
Problem is the Order model has two association with the same Address model:
class Order < ActiveRecord::Base
#...
belongs_to :billing_address, :class_name => 'Address'
belongs_to :shipping_address, :class_name => 'Address'
#...
end
So I need to set up my Checkout form to use Address model twice. The temporary approach I used to apply was trivial. However it was working fine:
class Checkout < Reform::Form
extend ::ActiveModel::Callbacks
#...
property :billing_address, populate_if_empty: Address do
property :firstname
property :lastname
property :address1
property :address2
property :phone
property :city
property :zipcode
property :country_id
property :billing_address_for_id
property :shipping_address_for_id
validates :firstname,
:lastname,
:address1,
:phone,
:city,
:zipcode,
:country_id,
presence: true
# provided by phony_rails gem
# validates phone number to be correct and plausible
# without country accordance
validates :phone, phony_plausible: { ignore_record_country_code: true }
# provided by validates_zipcode gem
# validates zipcode to be correct due to country alpha2 code
validates :zipcode, zipcode: { country_code: :country_code }
end
property :shipping_address, populate_if_empty: Address do
property :firstname
property :lastname
property :address1
property :address2
property :phone
property :city
property :zipcode
property :country_id
property :billing_address_for_id
property :shipping_address_for_id
validates :firstname,
:lastname,
:address1,
:phone,
:city,
:zipcode,
:country_id,
presence: true
# provided by phony_rails gem
# validates phone number to be correct and plausible
# without country accordance
validates :phone, phony_plausible: { ignore_record_country_code: true }
# provided by validates_zipcode gem
# validates zipcode to be correct due to country alpha2 code
validates :zipcode, zipcode: { country_code: :country_code }
#...
end
But it's obvious that duplicated code must be refactored. And there I found that I can't come up with any working solution. My last attempt was like following:
class Checkout < Reform::Form
extend ::ActiveModel::Callbacks
#...
property :billing_address, populate_if_empty: Address, form: BillingAddress
property :shipping_address, populate_if_empty: Address, form: ShippingAddress
#...
end
class BillingAddress < Reform::Form
extend ::ActiveModel::Callbacks
include Address
end
class ShippingAddress < Reform::Form
extend ::ActiveModel::Callbacks
include Address
end
module Address
include Reform::Form::Module
property :firstname
property :lastname
property :address1
property :address2
property :phone
property :city
property :zipcode
property :country_id
property :billing_address_for_id
property :shipping_address_for_id
validates :firstname,
:lastname,
:address1,
:phone,
:city,
:zipcode,
:country_id,
presence: true
# provided by phony_rails gem
# validates phone number to be correct and plausible
# without country accordance
validates :phone, phony_plausible: { ignore_record_country_code: true }
# provided by validates_zipcode gem
# validates zipcode to be correct due to country alpha2 code
validates :zipcode, zipcode: { country_code: :country_code }
end
And with that setup
@checkout = Checkout.new(@order)
was giving me the error
undefined method `active_record' for #Declarative::Heritage:0x007ff6ea6fb038
So is there any standard approach in Reform to make things above work? Or can anybody tell what I do wrong? Thanks!
Accidentally I've found an answer. The actual problem was my module name was Address what is an exactly name of one of my models. And it made some conflict obviously. So I've changed Address to AddressModule.
And my working setup will be:
class Checkout < Reform::Form
extend ::ActiveModel::Callbacks
#...
property :billing_address, populate_if_empty: Address, form: BillingAddress
property :shipping_address, populate_if_empty: Address, form: ShippingAddress
#...
end
class BillingAddress < Reform::Form
extend ::ActiveModel::Callbacks
include AddressModule
end
class ShippingAddress < Reform::Form
extend ::ActiveModel::Callbacks
include AddressModule
end
module AddressModule
include Reform::Form::Module
property :firstname
property :lastname
property :address1
property :address2
property :phone
property :city
property :zipcode
property :country_id
property :billing_address_for_id
property :shipping_address_for_id
validates :firstname,
:lastname,
:address1,
:phone,
:city,
:zipcode,
:country_id,
presence: true
# provided by phony_rails gem
# validates phone number to be correct and plausible
# without country accordance
validates :phone, phony_plausible: { ignore_record_country_code: true }
# provided by validates_zipcode gem
# validates zipcode to be correct due to country alpha2 code
validates :zipcode, zipcode: { country_code: :country_code }
end