如何使用JQuery/Ajax(和Rails)执行复杂的服务器端表单验证?

4
我正在使用Rails构建一个问答应用程序,其中包含许多复杂的验证(例如,用户不能对自己的问题进行投票,或者重复对同一问题进行投票等)。我一直在使用Ajax+JQuery来更新页面上的内容,如果请求成功,则会更新内容,但如果存在问题,则希望能够显示有用的错误消息。虽然我没有问题进行客户端验证,例如检查字段是否为空,但是对于像投票自己的问题这样的情况,我所能做的最好的办法就是防止在Votes控制器中执行任何JavaScript,以便不会更新投票计数器。就像这样:
if @vote.save
  respond_to do |format|
    format.html {redirect_to :back}
    format.js
  end
else
  respond_to do |format|
    flash[:error] = "Sorry, there was an error."
    format.html {redirect_to :back}
  end

结束

如果我尝试为自己的问题投票,StackOverflow会给我一个错误消息,所以我知道这是可以做到的!

谢谢

2个回答

1

服务器端验证

在您的投票模型中:

validates_uniqueness_of :current_user

保留您传统的控制器设置以进行编辑和保存。

然后使用jQuery:

$(".vote_link").submit(function(){
  $.ajax({type: "POST", 
          url: $(this).attr("action"), 
          data: $(this).serialize(), 
          dataType: "script",
          error: function(){ $("#message").show().html("You can't vote on this!")},
          success: function(){ $("#message").show().html("You voted!")};
          });
  return false;
});

而你的HTML/HAML:

= link_to 'Vote on This', new_vote_path(object)

是的,上面的验证可以工作,但如果验证未通过(这就是我的代码已经执行的操作),它只会回复false,而不会发送一个关于错误原因的Ajax消息。底部的代码对我来说不太合理。那是要放在JavaScript文件中吗?.js文件没有像@question这样的变量访问权限,对吧? - kateray
你是不是想完全避开Ruby?我得考虑一下(使用纯ajax来解决这个问题..)。但是底部的示例可以通过html/haml进行使用。Haml是HTML的简写,语法有点不同。它就是没有<% -if blah blah blah %>这样的语句。只需添加<%即可。 - Trip
我对 Ruby 没有任何问题,我已经编写了所需的验证,做到了我想要的一切。问题是,我正在使用 Ajax 更新页面上的各种元素(例如投票计数),如果请求未成功,则不应更新这些元素。如果请求未成功,应该显示错误消息。问题在于,我需要发送一个 HTML 请求来检查这些验证 - 这就是我想通过 Ajax 找到一种方法来做到这一点的原因。 - kateray
嗯,所以你建议在我的控制器中执行验证而不是模型? - kateray
以上已更新。抱歉,我可能一直在疯狂地谈论控制器。模型也可以使用,但我个人会避免这样做,因为它对数据库的负担更重,而你本可以在此之前加载所有内容。 - Trip
奇怪,它就是没用!我完全复制了你的例子,但似乎没有发送Ajax请求,只刷新了普通的HTML... - kateray

1

保留您的验证,生成HTML以便通过JavaScript作为响应返回并插入到指定位置,例如(使用jQuery):

votes/create.js.erb:

<% if @vote.errors %>
  $('#vote_form').html("<%= escape_javascript(render(:partial => 'form').html_safe) -%>");
<% else %>
  $('#vote_form').html("<%= escape_javascript(render(:partial => 'success').html_safe) -%>");
<% end %>

这将为您省下一些麻烦。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接