Rails 3 UJS - 控制器被link_to:remote调用两次

时间:2010-11-20 08:40:17

标签: jquery ruby-on-rails-3 ujs

我有一个奇怪的问题,JQuery正在为link_to方法创建两个AJAX请求。我正在使用JQuery for UJS开发Rails 3应用程序。我有一个切换链接,可以在“关注”和“取消关注”之间切换

我的链接呈现如下:

<span id="follow_link">
  <a href="/tfollow_artist?id=8103103" data-method="post" data-remote="true" id="follow_artist" rel="nofollow">Unfollow</a>
</span>

我的控制器设置如此:

def tfollow_artist
  @artist = Artist.find(params[:id])
  if current_user.following?(@artist) 
    current_user.stop_following(@artist)
  else 
    current_user.follow(@artist)
  end
 end

最终将js呈现为:

 $('#follow_link').html('<%= escape_javascript(render :partial => "follow") %>');

本质上取代了'&lt; span id =“follow_link”&gt; ...&lt; / span&gt;的html内容使用相同的URL只与文本不同。例如,上面将呈现为:

<span id="follow_link">
  <a href="/tfollow_artist?id=8103103" data-method="post" data-remote="true" id="follow_artist" rel="nofollow">Follow</a>
</span>

然而,这在某种程度上导致JQuery发出两个AJAX请求。

任何人都能看到这里有什么问题吗?

我正在使用'jquery-rails'gem,它正在将最新的jquery-ujs文件复制到我的应用程序中。 JQuery版本是1.4.3

11 个答案:

答案 0 :(得分:26)

感谢这个对话:

https://github.com/rails/jquery-ujs/issues/208

我能够发现jquery和jquery_ujs被包含两次。

我想jquery-rails gem会自动将它们放入application.js,然后我也将它们包含在application.js中。

似乎无论出于什么原因,application.js会自动捆绑app / assets / javascripts /中的所有内容 - 即使我删除 all 所需的内容。

所以,如果你的:remote =&gt;真实表单将被提交两次,请尝试检查application.js。

希望这有帮助!

更新:我相信这可能与我预先渲染我的资产而不使用摘要有关,所以当我的开发环境在html头中根据app / assets / application中的需求动态添加脚本标签时。 js,它还为一个空的动态application.js添加一个,除了来自public / assets的静态一个被加载。混乱?是的!

答案 1 :(得分:17)

我有同样的问题,通过评论此行修复

\#config.assets.debug = true

处于开发模式

答案 2 :(得分:5)

我有同样的问题。在rake任务之后运行解决了我的问题。

rake tmp:clear
rake assets:clean

答案 3 :(得分:3)

我认为正在发生的事情是您的JavaScript没有阻止链接被浏览器执行。所以你得到了AJAX请求然后是浏览器请求。

在Rails Cast 174中有一个解释和解决方案。文字解释here,大约是页面的3/4。

答案 4 :(得分:2)

我遇到了同样的问题:使用时重复请求:remote =&gt;真正。我的问题是由于使用Heroku和预编译资产。我在部署到Heroku之前预编译资产(rake资产:预编译)。这实质上是在公用文件夹中创建资产管道的副本。因此,Docunext提到了同样的事情:处理每个请求时有多个javascript文件。

如果我在本地工作时删除公共目录中的资产(git rm -rf public / assets),它会得到修复。从公共目录中删除资产后,它停止发送多个请求

答案 5 :(得分:1)

尝试此代码....以防止双击远程链接..

$('a[data-remote=true]').live('ajax:before', function () {
   if ($(this).attr('ajax-loading')) {
     return false;
   } else {
     $(this).attr('ajax-loading', true);
   }
}).live('ajax:complete', function () {
  $(this).removeAttr('ajax-loading');
});

Gist

答案 6 :(得分:1)

同样对我来说同样的问题:两次XMLHttpRequest上 link_to ...:remote =&gt; “真”

我已经解决了,

locals / application.rb

通过评论

// config.assets.paths&lt;&lt; Rails.root.join( '供应商', '资产', '样式表', 'Java脚本')

并取消注释

config.action_view.javascript_expansions [:defaults] =%w(jquery jquery-ui application)

然后我忘了做最后一次git拉。 我希望能帮助别人。

答案 7 :(得分:0)

您想要的JavaScript文件:defaults(始终包含application.js)。

 config.action_view.javascript_expansions[:defaults] = %w(jquery rails)

注释行显然是说application.js总是包含在内。 在我的应用程序中,我添加了默认应用程序。所以对于ajax .submit,它在我的应用程序中创建了两条记录。

答案 8 :(得分:0)

我刚才面临同样的问题。检查了所有代码更改并尝试了其他的东西,但没有用。最后清除了浏览器缓存。这有帮助。

答案 9 :(得分:0)

如果您无法找到两次加载ujs文件的位置,只需将此代码复制到rails.js / application.js(最好不在此处)

var alreadyInitialized = function() {
    var events = $(document).data('events');
    return events.click && $.grep(events.click, function(e) { return e.namespace === 'rails'; }).length;
    }

if ( alreadyInitialized() ) {
    $.error('jquery-ujs has already been loaded!');
}

答案 10 :(得分:0)

根据Eugene的回答,请注意,如果您在本地预编译资产进行生产后正在开发,例如...

bundle exec rake assets:precompile RAILS_ENV=production

...然后当您继续开发时,Rails AssetPipeline将希望两者您的未编译的您的编译资产。

解决这个问题的一种方法是使用Eugene的Rails标准rake任务。另一种方法是简单地删除那些讨厌的预编译生产就绪资产,如

$ rm -rf #{Rails.root}/public/assets