我有一个简单的应用程序,要求用户输入他们的起始和结束地址,一旦他们这样做,他们就可以点击提交并获得下一个到目的地的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中知道我可以抛出异常或其他东西。
答案 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
希望你明白了吗?