Реформа драгоценный камень: использовать одну модель для нескольких форм

Я использую гем Reform, чтобы сделать объект формы для оформления заказа в моем интернет-магазине. У меня есть форма Checkout, которая содержит свойства для модели Order, которая связана с моделью Address.

Проблема в том, что модель Order имеет две ассоциации с одной и той же моделью Address:

class Order < ActiveRecord::Base
  #...
  belongs_to :billing_address, :class_name => 'Address'
  belongs_to :shipping_address, :class_name => 'Address'
  #...
end

Поэтому мне нужно настроить форму Checkout для использования модели адреса дважды. Временный подход, который я использовал, был тривиален. Однако это работало нормально:

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

Но очевидно, что дублированный код должен быть реорганизован. И там я обнаружил, что не могу найти никакого рабочего решения. Моя последняя попытка была такой:

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

И с этой настройкой

@checkout = Checkout.new(@order)

давал мне ошибку

undefined method `active_record' for #Declarative::Heritage:0x007ff6ea6fb038

Так есть ли какой-то стандартный подход в реформе, чтобы заставить вещи работать выше? Или кто-нибудь может сказать, что я делаю не так? Спасибо!

1 ответ

Решение

Случайно я нашел ответ. На самом деле проблема была в том, что имя моего модуля было Address, что является точным названием одной из моих моделей. И это привело к определенному конфликту. Поэтому я изменил адрес на AddressModule.

И моя рабочая установка будет:

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
Другие вопросы по тегам