自定义验证,错误消息无法显示

时间:2019-02-08 13:05:26

标签: ruby-on-rails

我有一个订单,可以让我的用户验证销售条件以便继续付款。

如果用户尚未选中该框,我希望得到警告。

我只是无法做到这一点...

  

更新(添加购物车)

订单在购物车中初始化:

class ShoppingCart

  delegate :sub_total, to: :order

  def initialize(token:)
    @token = token
  end

  def order
    @order ||= Order.find_or_initialize_by(token: @token, status: 0) do |order|
      order.sub_total = 0
    end
  end
end

orders / new.html.erb

中的表格
<%= simple_form_for @order, url: clients_checkout_path do |f| %>
  <div class="<%= 'error_message' if @order.errors.full_messages.any? %> ">
   <% if  @order.errors.any? %>
     <% @order.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
     <% end %>
    <% end %>
 </div>
  <%= f.hidden_field :user_id %>
  <%= f.input :cgos_accepted, as: :boolean, checked_value: true, unchecked_value: false %>
  <%= f.submit, class: "btn btn-main btn-block" %>
<% end %>

这是控制器:

class Clients::OrdersController < Clients::ApplicationController

    def index
        @orders = Order.all
        @orders = @orders.filter_by_status(params[:status]) if params[:status]
    end

    def show
        @order = Order.find(params[:id])
    end

    def new
        @order = current_cart.order
        @billing_address = BillingAddress.new
    end

    def create
        @order = current_cart.order
        @order.update_sub_total!
        @order.update_total!
        if @order.update_attributes!(order_params.merge(user_id: current_user.id))
        redirect_to new_clients_order_payment_path(@order)
        end
    end

    private

    def order_params
        params.require(:order).permit(:status,  :user_id, :token , :sub_total, :cgos_accepted)
    end
end

在订单模型中,我添加了一个验证:

class Order < ApplicationRecord
  validate :accept_cgos, on: :update
  #[...]
  private 

  def accept_cgos
    if self.cgos_accepted == false
      errors.add(:base, :must_accept_cgos)
    end
  end
end

我的yml文件是:

en:
  activerecord:
    errors:
      models:
        order:
          attributes:
            base:
              must_accept_cgos: Please accept the general condition of sales

我期望警告消息会显示在div中,但它会打开“更好的错误”并显示:

ActiveRecord::RecordInvalid at /clients/cart/checkout
Validation failed: Please accept the general condition of sales

所以它有点用,但是为什么它不显示在我的错误div中?

2 个答案:

答案 0 :(得分:2)

update_attributes!

您正在使用update_attributesupdate_attributes!的爆炸式版本。就像save!create!一样,如果保存失败,它将引发异常。

如果您在该方法调用中删除了感叹号,则update_attributes在无法保存时将返回false。

呈现错误

缺少的另一部分是在发生验证错误的情况下呈现new模板。如果update_attributes返回true,将发生重定向,但是如果返回false,则rails将默认尝试渲染create.html.erb。但是在这种情况下,也可以使用new模板,但是必须告知rails这样做。

代码更改

更改后的实现可能看起来像这样。

 if @order.update_attributes(order_params.merge(user_id: current_user.id)) # no bang
    redirect_to new_clients_order_payment_path(@order)
 else
   @billing_address = BillingAddress.new                                   # because the #new template requires it.
   render :new
 end

答案 1 :(得分:1)

  

为什么它不显示在我的错误div中?

由于您的create操作,您正在执行redirect_toredirect_to刷新了order实例,并且所有来自对象的错误都消失了,请尝试添加改为render :new

# for example
def create
  if @order.updated
    redirect_to path
  else
    render :new
  end
end