я не буду отправлять @order
через form_with
в Rails 5.2.@order
является экземпляром класса Order
, который имеет сериализованный столбец для полей адреса.Поля адреса заполняются на fields_for
в форме заказа, при отправке формы на OrdersController
все поля / значения передаются корректно.
Проблема в том, что если @order
не проходит проверку, OrdersController
снова отображает представление формы с ошибками @order
, но здесь адрес fields_for не заполняется хэшем :address
.
Я видел довольно хакерские решения для преобразования сериализованного столбца в attr_accessors. Есть ли удобное решение для заполнения полей формы из сериализованного столбца в Rails?
Вот мой код…
order.rb
class Order < ApplicationRecord
serialize :address
…
validate :address_validator
…
private
def address_validator
required_fields = [:firstname, :lastname, :line1, :city, :postal_code, :country]
required_fields.each do |field|
self.errors.add(:base, "Address / #{field.to_s.titleize} can't be blank") if self.address[field.to_s].blank?
end
end
…
end
new.html.erb
<%= form_with model: @order, id: 'order-form', class: 'form', local: true do |f| %>
<%= render 'shared/form_errors', object: f.object %>
…
<%= f.fields_for :address do |g| %>
<%= render 'orders/address_fields', f: g %>
<% end %>
…
<% end %>
_address_fields.html.erb
<div class='form__row columns columns--responsive-to-small columns--with-gutter'>
<div class='form__input form__input--mandatory'>
<%= f.label :firstname, 'Firstname' %>
<%= f.text_field :firstname %>
</div>
<div class='form__input form__input--mandatory'>
<%= f.label :lastname, 'Lastname' %>
<%= f.text_field :lastname %>
</div>
</div>
<div class='form__row'>
<div class='form__input form__input--mandatory'>
<%= f.label :line1, 'Address (line 1)' %>
<%= f.text_field :line1 %>
</div>
</div>
…
После отправки формы объект @order имеет следующие значения (значения адреса присутствуют)
(byebug) @order
#<Order id: nil, order_id: "HvMB00KS-73e1fc", …, created_at: nil, updated_at: nil, address: {"firstname"=>"Rocky", "lastname"=>"Marciano", "line1"=>"Saplestreet 123", "line2"=>"", "city"=>"Clashtown", "postal_code"=>"18726", "country"=>"Germany"}, email: "test@mail.com", products: … >
Спасибо!