第5条:验证表单的方法

问题描述 投票:2回答:1

我将尽可能详细地解释我的问题。

基本上我有一个新的Rails形式:

 <%= form_for(@contact, html: {multipart: true}) do |f| %>

      <div class="card">
        <div class="card-header">
          <h2 class="display-5 main-text-blue text-center font-weight-bold">Add New Contact</h2>
        </div>
        <div class="card-body">

     <div class="errors">
                <% if @contact.errors.any? %>
                    <div class="alert alert-danger">
                       <h5 class="text-center mb-n1 pb-1"><i class="fa fa-exclamation-triangle text-danger"></i> Please correct the following errors: </h5>
                   </div>
                <% end %>
            </div>

          <div class="form-group row">
            <div class="col-md-5 mx-auto">

            <div class="wrap" id="avatar-container">
                  <div class="valign-middle">
                      <div class="form-group">
                          <% if @contact.new_record? %>
                             <%= image_tag "100x100.png", class: "img-responsve img-preview" %>
                          <% else %>
                              <%= image_tag @contact.avatar, class: "img-responsve img-preview" %>
                             <% end %>
                          <label for="file" class="sr-only">Choose Image</label>
                           <%= f.file_field :contact_avatar, id: "file" %>
                      </div>
                  </div>
              </div>

            </div>
          </div>


          <div class="form-group row">
            <%= f.label :name, class: "col-lg-2 col-form-label" %> 
            <div class="col-lg-10">
              <%= f.text_field :name, class: "form-control #{'is-invalid' if has_error?(@contact, :name) }", id: "name", placeholder: "Name.." %>
                <% if has_error?(@contact, :name) %>
                      <span class="text-danger">
                          <%= get_error(@contact, :name)%>
                      </span>
                <% end %>
            </div>
          </div>


          <div class="form-group row">
             <%= f.label :email, class: "col-lg-2 col-form-label" %> 
            <div class="col-lg-10">
              <%= f.text_field :email, class: "form-control #{'is-invalid' if has_error?(@contact, :email) }", id: "email", placeholder: "Email.." %>
             <% if has_error?(@contact, :email) %>
                      <span class="text-danger">
                          <%= get_error(@contact, :email)%>
                      </span>
                <% end %>
            </div>
          </div>

          <div class="form-group row">
            <%= f.label :mobile, class: "col-lg-2 col-form-label" %> 
            <div class="col-lg-10">
              <%= f.text_field :mobile, class: "form-control #{'is-invalid' if has_error?(@contact, :mobile) }", id: "mobile", placeholder: "Mobile.." %>
              <% if has_error?(@contact, :mobile) %>
                      <span class="text-danger">
                          <%= get_error(@contact, :mobile)%>
                      </span>
                <% end %>
            </div>
          </div>


          <div class="form-group row">
             <%= f.label :phone, class: "col-lg-2 col-form-label" %> 
            <div class="col-lg-10">
             <%= f.text_field :phone, class: "form-control #{'is-invalid' if has_error?(@contact, :phone) }", id: "phone", placeholder: "Phone.." %>
              <% if has_error?(@contact, :phone) %>
                      <span class="text-danger">
                          <%= get_error(@contact, :phone)%>
                      </span>
                <% end %>
            </div>
          </div>


          <div class="form-group row">
            <%= f.label :country, class: "col-lg-2 col-form-label" %>
            <div class="col-lg-10">
               <%= f.text_field :country, class: "form-control", id: "country", placeholder: "Country.." %>
            </div>
          </div>


          <div class="form-group row">
            <%= f.label :address, class: "col-lg-2 col-form-label" %>
            <div class="col-lg-10">
              <%= f.text_field :address, class: "form-control", id: "address", placeholder: "Address.." %>
            </div>
          </div>
          <div class="form-row">
             <%= f.label :location, class: "col-lg-2 col-form-label" %>
            <div class="col-4">
             <%= f.text_field :city, class: "form-control", id: "city", placeholder: "City.." %>
            </div>
            <div class="col-4">
              <%= f.text_field :state, class: "form-control", id: "state", placeholder: "State.." %>
            </div>
            <div class="col-2">
               <%= f.text_field :zip, class: "form-control", id: "zip", placeholder: "Zip.." %>
            </div>
          </div>
          <div class="form-group row category-mt">
             <%= f.label :category, class: "col-lg-2 col-form-label" %>
            <div class="col-lg-5">
                <%= f.collection_select :category_id, Category.all, :id, :name, { prompt: "Select Category" }, id: "category_select", class: "form-control #{'is-invalid' if has_error?(@contact, :category) }" %>
                 <% if has_error?(@contact, :category) %>
                      <span class="text-danger">
                          <%= get_error(@contact, :category)%>
                      </span>
                <% end %>
            </div>
            <div class="col-lg-3">
              <a class="btn btn-outline-secondary add-category-button btn-block mt-1" href="#" id="add-category-btn">Add Category</a>
            </div>
          </div>

          <div class="form-group row" id="add-new-category">
            <label class="col-lg-2 col-form-label" for="location">New Category:</label>
            <div class="col-lg-10">
              <div class="input-group">
                    <input id="new-category" name="new-category" class="form-control <%= 'is-invalid' if has_error?(@category, :name)  %>"  placeholder="Enter category name" type="text">
                     <% if has_error?(@category, :name) %>
                      <span class="text-danger">
                          <%= get_error(@category, :name)%>
                      </span>
                    <% end %>


                <div class="input-group-append">
                    <button class="btn btn-outline-secondary category-btn" id="save-new-category-btn" type="button"><i class="fa fa-check"></i></button>
                </div>
              </div>
            </div>
          </div>

          <div class="form-group row">
              <%= f.label :note, class: "col-lg-2 col-form-label" %>
            <div class="col-lg-10">
               <%= f.text_area :note, class: "form-control", id: "note", placeholder: "Note..", rows: "3" %>
            </div>
          </div>
        </div>
        <div class="card-footer">
           <%= f.submit "Save", class: "btn btn-primary border-button mb-3 ml-3", id: "save-btn" %>
           <a class="btn btn-outline-secondary border-button mt-n3" data-dismiss="modal" href="#" id="cancel-btn">Cancel</a>
        </div>
      </div>

       <% end %>

正如您在这里看到的,我放置了一些已经在联系人模型中存在的Rails验证代码。例如:

<%= f.text_field :name, class: "form-control #{'is-invalid' if has_error?(@contact, :name) }", id: "name", placeholder: "name.." %>

如果有任何错误,将添加类is-invalid。还有:

<% if has_error?(@contact, :phone) %>
<span class="text-danger">
<%= get_error(@contact, :phone)%>
</span>
<% end %>

如果有错误,仅将错误文本显示在底部。这是该代码的帮助程序:

def has_error?(resource, field)
     resource.errors.messages[field].present?
  end

  def get_error(resource, field)
    msg = resource.errors.messages[field]
    field.to_s.capitalize + " " + msg.join(' and ') + '.'
  end

所以,基本上,我在这里处理两个表:Contact和Category。到目前为止,我在表单上确认的大部分是联系人。我在这里具有此功能,用户可以在其中通过ajax在联系人表上的外键即刻添加NEW CATEGORY,也可以在上面的代码中看到。

enter image description here

现在,据我所知,我还可以对模型进行验证。因此,我尝试对类别进行验证:

 validates :name, uniqueness: true

我希望这将验证输出的新类别的唯一性,这意味着如果数据库中已存在文本(类别名称),则它必须禁止它并引发错误。所以我要做的是尝试以下代码来显示错误:

<input id="new-category" name="new-category" class="form-control <%= 'is-invalid' if has_error?(@category, :name)  %>"  placeholder="Enter category name" type="text">
<% if has_error?(@category, :name) %>
<span class="text-danger">
 <%= get_error(@category, :name)%>
</span>
<% end %>

所以我以为它会工作,但是会抛出一个错误我认为undefined method errors' for nil:NilClass应该有效,因为我正在使用@category,但后来我意识到这是@contact的一种形式。

是否有更好的方法可以使此项工作并在添加新类别字段上显示错误?我真的很坚持。我希望有一个人可以帮助我。

ruby-on-rails
1个回答
1
投票

您可以通过f对象获得类别错误

© www.soinside.com 2019 - 2024. All rights reserved.