【发布时间】:2011-12-11 21:05:01
【问题描述】:
如下所示,我在一个 Rails 3.1 应用程序中尝试使用块使用 link_to 进行 POST:
views/wall/_problem.html.erb
<li data-icon="check">
<%= link_to(
url_for(
:controller => 'completed_problems',
:action => 'create',
:problem_id => "#{problem.id}"),
{:class => "wall_problem",
:confirm => "Climbed it?",
:remote => true,
:"data-type" => "json",
:method => "POST"}) do %>
<div>stuff</div>
<% end %>
</li>
views/wall/show.html.erb
<% content_for :content do %>
<div data-role="content">
<ul data-role="listview">
<%= render :partial => 'problem', :collection => @wall.live_problems.sort %>
</ul>
<% end %>
<script>
$('.wall_problem').live('ajax:success', function() {
alert("Success!");
});
</script>
此特定 POST 指向以下控制器操作:
controllers/completed_problems_controller.rb
class CompletedProblemsController < ApplicationController
# POST /completed_problems
def create
@problem = Problem.find(params[:problem_id]
@completed_problem = @problem.completed_problems.build
if @completed_problem.save
render :json => { }
else
render :json => { :location => root_url}
end
end
end
正如您从下面的日志中看到的那样,POST 确实成功了,但由于某种原因,应用程序同时对完全相同的 URL 执行 GET。
日志
Started POST "/completed_problems?problem_id=11" for 127.0.0.1 at 2011-12-11 13:13:06 -0500
Processing by CompletedProblemsController#create as JSON
Parameters: {"problem_id"=>"11"}
# SQL stuff snipped from here
Completed 200 OK in 116ms (Views: 3.0ms | ActiveRecord: 2.6ms)
Started GET "/completed_problems?problem_id=11" for 127.0.0.1 at 2011-12-11 13:13:06 -0500
Processing by CompletedProblemsController#index as HTML
Parameters: {"problem_id"=>"11"}
Rendered completed_problems/index.html.erb within layouts/application (29.6ms)
Completed 500 Internal Server Error in 36ms
这个问题在范围上确实与jQuery ajax POST causes an immediate GET to the same URL 相似,但这是使用 jquery_ujs,我不相信我已经留下任何自定义 jquery 代码。因此,我无法执行添加'return false;'的问题中建议的解决方案
我怀疑问题出在以下三个地方之一:
- 我使用带有块的 link_to 元素的语法不正确
- 我在控制器中对请求的处理不正确
- 不知何故,我的 jquery_ujs 翻了一番(我真的不认为这是真的,但它可能在这里)
编辑
缩小问题 #1:
我将脚本更改为以下内容,
<script>
$('.wall_problem').live('ajax:beforeSend', function() {
return false;
});
</script>
并发现 POST 现在没有通过,但 GET 确实通过了,确认问题似乎是 AJAX 处理程序正在拾取链接并将其作为 POST 正确提交,但没有拦截 GET浏览器提交。
缩小问题 #2:
一开始我没有提到它,但我使用的是 Jquery-mobile。现在在将脚本标记恢复到以前的形式然后禁用 jquery-mobile 时,我再次尝试了该链接,它现在不提交 GET 但提交了 POST。这让我相信 jquery-ujs 和 jquery mobile 如何与链接交互存在一些问题。
【问题讨论】:
-
一个问题是否有多个已完成问题?或者,问题是完成还是未完成。如果是后者,我只会在 Post 表中有一个布尔值来说明它是否已完成。然后,您可以对问题控制器更新操作进行简单的 AJAX 调用,并将完成的属性设置为 ture 或 false。我不确定这是否是您的应用程序的构建方式,但如果是,我会发布关于如何解决它的答案。
-
CompletedProblem 对象实际上是用户和问题之间的连接对象,所以我认为这不会有帮助。这样做似乎也只是解决更大问题的方法。
-
如果用户有_很多问题并且问题属于_用户,则不需要加入。使用简单的布尔字段,您可以执行
user.problems.where(:completed => false)之类的范围。这不是一种解决方法。更简单的代码 => 更少的问题。此外,您可以编写自己的 Jquery 函数来处理 AJAX POST,然后在响应中使用 .js.erb 模板更新您的视图
标签: jquery ruby-on-rails rails-activerecord