I have two rails applications that communicate together.
In the first application i have the following method in my controller:

def delivery_status
  envelope = Envelope.find(params[ : id])
  render : json => envelope.to_json
end

which, if go to the url in my browser, nicely shows my the JSON. Seems ok.
However, if i call this through jQuery, from my second application, using the following:

    $(document).ready(function(){
      $('.get_sms_details').live('click', function(event) {
          var el = $(this),
              data_url = el.attr('data-url');
          $.ajax({
            url: data_url,
            dataType: 'text',
            success: function(data, status, req) {
              alert('received with status' + status)
              alert('received json ' + data);
            }
          });
      });
    });

then the right url is hit with the correct parameters but data is always empty.
I first tried using $.getJSON, then $.get to end at $.ajax. I am not sure but it seemed i was doing something wrong at server-side.
The request looked fine inside firebug, but the response was always empty. Yet, i did not understand, if let the browser hit the same url, i got my json object.

So how do you solve this? Well, i was reading the documentation of $.ajax, and there i found:

When data is retrieved from remote servers (which is only possible using the script or jsonp data types), the operation is performed using a script tag rather than an XMLHttpRequest object.

So, jsonp was the way, but how?

First, i changed my jQuery code:

$(document).ready(function(){
    $('.get_sms_details').live('click', function(event) {
        var el = $(this),
            data_url = el.attr('data-url');
        data_url = data_url
        $.ajax({
          url: data_url,
          dataType: 'jsonp',
          success: function(data) {
              envelope = data.envelope;
              alert('received envelope ' + data.envelope.id);
          }
        });
    });
});

but then my server-side needed to be able to handle the jsonp.

I handled that using the following code:

  def delivery_status
    envelope = Envelope.find(params[ :id])
    render_json envelope.to_json(:include => [: deliveries, : log_lines])
  end

  private

  # render json, but also allow JSONP and handle that correctly
  def render_json(json, options={})
    callback, variable = params[:callback], params[:variable]
    logger.debug("render json or jsonp? Callback = #{callback}, Variable=#{variable}")
    response = begin
      if callback && variable
        "var #{variable} = #{json};\n#{callback}(#{variable});"
      elsif variable
        "var #{variable} = #{json}"
      elsif callback
        "#{callback}(#{json});"
      else
        json
      end
    end
    render({:content_type => :js, :text => response}.merge(options))
  end

Where the render_json does all the dirty work for me :)

I was somewhat expecting this to be standard inside rails3, and as Kevin Chiu pointed out in the comments, it is and much simpler at that:

  def delivery_status
    envelope = Envelope.find(params[ :id])
    render :json => envelope.to_json(:include => [: deliveries, : log_lines]), :callback => params[:callback]
  end

Awesome :)