IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    How do you dynamically set AJAX request data with Rails 3.1, jQuery, CoffeeScript, and all that jazz?

    My Web Log Book发表于 2011-06-24 12:17:00
    love 0

    Rails 3.1 is awesome. CoffeeScript is great. The jQuery addition is brilliant. But recently I came across a simple problem that took quite a while to figure out and with all these additions being fairly new, there was not much online help available, so I had to turn to the source code.

    So what was the problem? How do we dynamically modify the AJAX request data with rails using a link_to. If I was using pure jQuery the solution would be as simple as,

    $.ajax('/some/path', {
        type: 'POST',
        data: { foo: 'bar' },
        success: function() { .. },
        error: function() { .. }
    });
    

    But since I was trying to keep it Railsy and use link_to to create a POST request, there were a few hurdles. Initially, I was trying to use the ajax:beforeSend event callback which was useless for this task, as all form data gets set before this callback is made by Rails. The only use of this callback would be to abort the ajax request altogether if you suddenly discovered something. So I had to use the ajax:before event. But inside the ajax:before callback, we are only passed an event object totally unrelated to ajax, so to set custom ajax data, I had to checkout how any data gets passed to jQuery.ajax by Rails in the first place. Here’s the relevant snippet from Rails UJS. Stripped out the form handling part as we’re dealing with a link here.

    if (rails.fire(element, 'ajax:before')) {
        if (element.is('form')) {
            ...
        } else {
            method = element.data('method');
            url = element.attr('href');
            data = element.data('params') || null;
        }
        ...
    }
    

    So Rails looks for custom data inside the params data object of the element triggering the ajax request which is where I had to implant it. The CoffeeScript code for intercepting the ajax request and injecting the data dynamically looked like,

    $ ->
        $('#my_link').bind('ajax:before', ->
            $(this).data('params', { foo: 'bar' })
        )
    

    Or if you don’t like CoffeeScript for some reason, here’s the equivalent in JavaScript.

    $(function() {
        $('#my_link').bind('ajax:before', function() {
            $(this).data('params', { foo: 'bar' });
        });
    });
    

    The corresponding link in rails erb was,

    <%= link_to 'Foo', foo_path, method: :post, remote: true, id: 'my_link' %>
    

    This new syntax of creating hashes in Ruby 1.9 is cool and almost similar to JavaScript’s object literals.



沪ICP备19023445号-2号
友情链接