当用户不提供输入时处理表单的正确方法

时间:2015-05-20 17:23:01

标签: ruby-on-rails ruby

我有一个简单的应用程序,要求用户输入他们的起始和结束地址,一旦他们这样做,他们就可以点击提交并获得下一个到目的地的3辆公共汽车/火车列表。但是,我无法处理用户根本没有输入任何内容并点击提交按钮的情况。

以下是简单表格的代码

   <%= form_tag("/welcome/index", method: "post") do %>
  <div class ="input-group">
  <label>Current Location</label>
  <%= text_field_tag("address", params['address'], :class => 'form-control') %>
</div><br/>
<div class ="input-group">
  <label>Destination Location</label>
  <%= text_field_tag("destaddress", params['destaddress'], :class => 'form-control') %>
  </div>


  <p>
    <br/>
<%= submit_tag "", :value => "Find Buses", :class => "btn btn-default" %>  </p>

<% end %>

这是我的控制器,我捕获用户的输入并运行我的逻辑以提供总线列表。

class WelcomeController < ApplicationController
  # displays the form, so change the name of the form you have now to new.html.erb
  def new
  end

  # the form will pass to this action to perform logic on longitude and latitude
  def create
    curAddress = params[:address]
    destAddress = params[:destaddress]



    #2 close stops to current location
    @currentList = Stop.by_distance(:origin => curAddress).limit(2)

    if @currentList.length == 0
      flash[:error] = "Somethig is wrong"
    end
    #2 closest stops to destination location
    @destList = Stop.by_distance(:origin => destAddress).limit(2)

    @startIds = Array.new
    2.times do |i|
      @startIds.push(@currentList[i].id)
    end

    @endIds = Array.new
    2.times do |i|
      @endIds.push(@destList[i].id)
    end


    @currentStop = Stop.closest(:origin => curAddress)
    @destinationStop = Stop.closest(:origin => destAddress)



         @timeNow = Time.now.in_time_zone("EST") + 1.hour
    @finalTime = @timeNow.strftime("%H:%M:%S")

    startStopId = @currentStop.first.id
    endStopId = @destinationStop.first.id

     #update it based on succeed
    @cStop = Stop.find(startStopId)
    @dStop = Stop.find(endStopId)




    testMethod(startStopId,endStopId)  


    render :index
  end

我所做的基本上是接受用户的输入,然后尝试使用名为Geokit的gem来找到用户的某个给定地址的两个最近的停靠点,并将它们的ID存储在@currentList and @destList

很明显,如果用户没有给出任何输入,那么这两个列表应该是空的。所以使用那个逻辑我尝试了这个

 if @currentList.length == 0
      flash[:error] = "Somethig is wrong"
    end

但是我无法处理用户没有输入的情况。所以我想知道如何处理它?理想情况下,我想在表单上显示“未输入输入”的消息,因此用户将重试输入一些输入,然后点击提交。我对rails上的ruby非常新,例如我在java中知道我可以抛出异常或其他东西。

2 个答案:

答案 0 :(得分:1)

def create ...

if params[:address].blank? || params[:destaddress].blank? # Checks if it is nil or = ""
  flash[:address_error] = "No address entered"
  render 'new' and return # render new shows the form again, return makes sure we
                          # don't do anything else in the action
                          # you can also do redirect_to, but this will be a little
                          # faster since you have no logic the new action
end

你应该在行动的早期做到这一点,这样你就不会在行动中浪费时间做其他事情。

正如Sharvy Ahmed所说,前端验证也是一个选择,也是一个好主意。他展示的HTML5方法的替代方案是JQuery,默认情况下rails使用。这可能看起来像这样。

$('form').submit(function() {  //When a form is submitted...
  $('input').each(function() { //Check each input...
    if ($(this).val() == "") { //To see if it is empty...
      alert("Missing address");//Say that it is
      return false;            //Don't submit the form
    }
  });
  return;                      //If we made it this far, all is well, submit the form
});

但是,您不应该依赖客户端验证,因为用户可以手动转到网址,绕过验证页面。

答案 1 :(得分:1)

首先,可以在前端和后端检查验证。

你可以使用html5 if ($sms["sender"] == $_POST['idOne']){ // $_POST['idOne'] instead of idOne 来强制输入字段,除非他们写东西,否则没有人可以继续。

required

对于后端验证,您可以检查字段是否不是<%= text_field_tag("address", params['address'], :class => 'form-control'), :required => true %> ,如下所示:

nil

顺便说一下,你将不得不重构代码。一个简单的重构可以声明一个私有方法来获取距离最近的位置ID,如下所示:

if curAddress && destAddress
  # Do your work here ...
end

然后在private def nearest_by_distance(address, n) Stop.by_distance(:origin => address).limit(n).pluck(:id) end 行动中,你可以做到:

create

希望你明白了吗?