序列化列的(Rails)字段没有填充数据



我不会在Rails 5.2中通过form_with提交@order@orderOrder类的实例,该类具有用于地址字段的序列化列。地址字段由订单表单中的fields_for填写,当将表单提交给OrdersController时,所有字段/值都被正确传递。

问题是:如果@order验证失败,OrdersController会再次呈现带有@order错误的表单视图,但这里的字段_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: … >

谢谢!

有一个方便的(没有充分记录的(解决方案,称为store_accessor,可以与序列化的属性哈希一起使用,以便为其键创建访问器。我发现这要归功于Nando Vieira的Using PostgreSQL和jsonb with Ruby on Rails。

使用上面的示例地址散列,我们可以定义…

class Order < ApplicationRecord
serialize :address
store_accessor :address, :firstname, :lastname, :postal_code, …
…
end

设置并读取地址的属性,如…

order = Order.new
order.firstame = 'Billy'
order.firstname
#=> "Billy"
order.address['firstname']
#=> "Billy"

在@订单的表格中,address的键可以直接设置,表格将分别填充…

<%= form_with model: @order, local: true do |f| %>
<%= f.label :firstname, 'Firstname' %>
<%= f.text_field :firstname %>
<%= f.label :lastname, 'Lastname' %>
<%= f.text_field :lastname %>
<% end %>

在OrdersController中使用强参数,如…

params.require(:order).permit(:firstname, :lastname)

相关内容

  • 没有找到相关文章

最新更新