违反验证时避免异常

时间:2016-10-25 21:14:19

标签: ruby-on-rails ruby

我在Ruby on Rails上没有经验,所以我需要你的帮助。

Visit.rb

class Visit < ActiveRecord::Base

    belongs_to          :employee
    belongs_to          :visitor
    default_scope   ->  { order(:created_at) }

    validates   :start,           presence: true,     uniqueness: {scope: [:end, :visitor_id]}
    validates   :end,             presence: true
    validates   :visitor_id,      presence: true
    validates   :employee_id,     presence: true
    validate    :valid_date_range_required

    def valid_date_range_required
        if (start && end) && (end < start)
            errors.add(:end, "must be after start")
        end
    end
end

schema.rb

create_table "visits", force: true do |t|
    t.datetime "created_at",                         null: false
    t.datetime "updated_at",                         null: false
    t.date     "start"
    t.date     "end"
    t.integer  "idVisit"
    t.integer  "employee_id"
    t.integer  "visitor_id"
    t.string   "status",      default: "Confirmed"
  end

  add_index "visits", ["start", "end", "visitor_id"], name: "index_visits_on_start_and_end_and_visitor_id", unique: true

在我的测试期间,如果我违反了唯一性验证或者:valid_date_range_required我的应用程序引发了一种阻塞自身的异常(例如:表单中的第一个参数不能包含nil或为空)。相反,我不希望应用程序显示它,但我希望应用程序在创建访问期间显示一些错误消息,以便用户可以以适当的方式填写表单。

愿你有人帮我理解一种方法吗?

修改

visits_controller.rb

class VisitsController < ApplicationController
    before_action :logged_in_employee,  only: [:create,    :destroy]
    before_action :correct_employee,    only: [:destroy,   :update ]

    def create
        @visit = current_employee.visits.build(visit_params)
        if @visit.save
            flash[:success] = "Visit added"
            redirect_to employee_path(session[:employee_id], :act => 'guestsVisits')
        else
            @visits = current_employee.visits.all
            @employee = current_employee
            @errors = @visit.errors.full_messages
            flash[:danger] = @errors
            render 'employees/guestsVisits'
        end
    end



    private

        def visit_params
            params.require(:visit).permit(:start, :end, :visitor_id, :employee_id)
        end
end

guestsVisits.rb (我的观点)

<div class="jumbotron3 text-center">
  <div class="row">
    <h1>Guests Visits</h1>
    <hr>
    <%=render :partial =>"layouts/sidebar"%>
    <div class="panel3">
        <div class="panel-body">
            <% if logged_in? %>
                <%=render :partial =>"shared/error_messages"%>

                  <a class="btn icon-btn btn-success pos" data-toggle="modal" data-target="#visitModal">
                <span class="glyphicon btn-glyphicon glyphicon-plus img-circle text-success"></span>
                Add a visit
                </a>

                <div id="visitModal" class="modal fade" role="dialog">
                <div class="modal-dialog">

                <div class="modal-content">

                <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Add a visit</h4>
                </div>

                <div class="modal-body">
                <%= form_for(@visit) do |f| %>

                <%= f.label :start_date %>
                <%= f.date_field :start, class: 'form-control',:value => (f.object.start.strftime('%m/%d/%Y') if f.object.start) %>
                <%= errors_for @visit, :start %><%if @visit.errors.any?%><br><%end%>

                <br>
                <%= f.label :end_date %>
                <%= f.date_field :end, class: 'form-control',:value => (f.object.end.strftime('%m/%d/%Y') if f.object.end) %>
                <%= errors_for @visit, :end %><%if @visit.errors.any?%><br><%end%>

                <br>
                <%= f.label :Visitor %>
                <%= f.collection_select :visitor_id, Visitor.all, :id, :full_name, { :class=> "form-control", :include_blank => ''}%>
                <%= errors_for @visit, :visitor_id %><%if @visit.errors.any?%><br><%end%>
                <br>
                <%= f.submit "Add visit", class: "btn btn-primary btn-color" %>
                <% end %>
                </div>

                <div class="modal-footer">
                <button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
                </div>

                </div>
                </div>
                </div>
                <% end %>
                </div>
       </div>
    </div>
  </div>

error_messages.rb

<% if @visit && @visit.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
      The form contains <%= pluralize(@visit.errors.count, "error") %>.Open the modal for more details
    </div>
  </div>
<% end %>

我需要的是,添加在开始日期之前的结束日期或添加已经在数据库中的记录(开始,结束,访问者),我可以在我的模态中显示错误而不阻止所有应用程序因为形式中的第一个参数不能包含nil或为空异常或类似。

非常感谢你。

1 个答案:

答案 0 :(得分:0)

这就是为与唯一性相关的错误创建自定义消息的方法。

validates   :start, presence: true, uniqueness: {scope: [:end, :visitor_id],    
message: ->(object, data) do 'Each start can only have one visitor and one end.' 
end
}

 class VisitsController

   def create 
     @visit = Visit.find(params[:id])
     if @visit.save
       flash.now[:success] = 'Visit created' 
       redirect_to @visit
     else
       @errors = @visit.errors.full_messages
       flash[:danger] = @errors
       redirect_to root_url 
     end 
   end 

http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html