【问题标题】:Conditional saving of field_for data in Rails在 Rails 中条件保存 field_for 数据
【发布时间】:2020-02-06 04:46:30
【问题描述】:

我有一个具有客户模型和地址模型的 Rails 应用程序。客户可以有多个地址。我创建了一个使用 field_for 的表单,因此用户可以在同一个表单上输入客户详细信息和地址。 这是模型

客户.rb

class Customer < ApplicationRecord
    has_many :addresses, dependent: :destroy
    accepts_nested_attributes_for :addresses
end

地址.rb

class Address < ApplicationRecord
  belongs_to :customer

  validates :atype, presence: true


  ADDRESSTYPE = %w(Billing Delivery Postal)
    validates :atype, inclusion: { in: ADDRESSTYPE }
end

这是表格。

<%= form_with(model: customer, local: true) do |f| %>
  <%= f.label :firstname %>
  <%= f.text_field :firstname %>
  <%= f.label :surname %>
  <%= f.text_field :surname %>
  <%= f.label :location %>
  <%= f.text_field :location %>
  <%= f.label :email %>
  <%= f.email_field :email %>
  <%= f.label :mobile_number %>
  <%= f.text_field :mobile_number %>
  <%= f.label :company %>
  <%= f.text_field :company_name_legacy %>
  <%= f.fields_for :addresses do |address| %>
        <%= address.label :address_type %>
        <%= address.select :atype, Address::ADDRESSTYPE %>
        <%= address.label :address_line_1 %>
        <%= address.text_field :line_1 %>
        <%= address.label :address_line_2 %>
        <%= address.text_field :line_2 %>
        <%= address.label :city %>
        <%= address.text_field :city %>
        <%= address.label :state %>
        <%= address.text_field :state %>
        <%= address.label :postcode %>
        <%= address.text_field :postcode %>
        <%= address.label :country %>
        <%= address.text_field :country %>     
   <% end %> 
  <%= f.submit %>
<% end %>

我保存新客户的控制器如下,

def new
        @customer = Customer.new
        @customer.addresses.build
    end

    def create
        @customer = Customer.new customer_params
        @customer.save

        redirect_to @customer
    end

如果地址的 Line_1 为空,我希望能够阻止保存地址。我不知道如何测试它是否为空,或者如何防止它被保存为拯救客户的一部分?任何建议将不胜感激!

【问题讨论】:

    标签: ruby-on-rails ruby forms


    【解决方案1】:

    虽然@Yakov 的回答在技术上是正确的,但它会显示验证错误,这有时是不希望的。

    如果您想在没有地址的情况下保存客户,您可以向客户模式添加回调,如下所示:

    before_save :mark_addresses_for_removal
    
    def mark_addresses_for_removal
      addresses.each do |address|
        address.mark_for_destruction unless address.address_line_1?
      end
    end
    

    如果 address_line_1 文本被清除,这也会导致在编辑客户时删除地址。

    【讨论】:

    • 谢谢!这正是我想要的。对我的模型稍作修正 - 测试是 address.line_1?干杯。
    【解决方案2】:

    您可以向Address 模型validates :atype, :line_1, presence: true 添加验证,然后像这样重写create 方法:

    def create
      @customer = Customer.new customer_params
      if @customer.save
        redirect_to @customer
      else
        render 'new'
      end
    end
    

    并添加一小段代码以在表单顶部显示错误:

    <% if @customer.errors.any? %>
      <ul>
        <% @customer.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    <% end %>
    

    【讨论】:

    • 此外,具有触发验证的字段将使用 field_with_errors 类包装 div 元素。您可以添加 CSS 样式以突出显示有错误的字段。
    猜你喜欢
    • 2015-11-29
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 2020-12-17
    相关资源
    最近更新 更多