views:

105

answers:

3

ok, rails 3 new developer here.

I want my jquery to be able to get a json object from the rails 3 application for projects. Here is my controller.

def yourprojects
  @projects = Projects.all(current_user)

  respond_to do |format|
    format.html # index.html.erb
    format.json  { render :json => @projects }
  end
end

I added the format.json line... in jquery i have:

$.ajax({url: '/projects/yourprojects', dataType: 'json'});

So that should work i thought. Instead the server is returning: "Template is missing" "Missing template ,,,, with {:locale=>[:en, :en], :handlers=>[:rjs, :rhtml, :builder, :rxml, :erb], :formats=>[:html]} in view paths"

do you need a template for a jsOn return? shouldn't the rails 3 app know how to format the json?

Routes File:

resources :projects do
    collection do
        get 'yourprojects'  
    end
end
A: 
:formats=>[:html]

That says the server is thinking that html is being requested. Try adding a .json to your path (and possible route) and that will force the format. TO make that would would need a route something like this:

map.your_projects '/projects/yourprojects.:format',
  :controller => 'projects',
  :action => 'yourprojects'

Somehow, someway, the params[:format] should be "json" for this request so the format handlers can do the right thing.

Squeegy
Thanks Squeegy, but is this for Rails 3? My config/routes looks like this to accommodate (also added to the question above): resources :projects do collection do get 'yourprojects' endend
WozPoz
Also, I thought Rails 3 was smart enough to determine the request type and serve the right response, ie why you can have so many different types of response types (html, js, json, xml) ?
WozPoz
I'm actually a bit behind and not sure how Rails 3 routes work. But 2.x worked like I describe. Sorry!
Squeegy
thanks from what I was able to find online it's totally different in Rails 3.
WozPoz
+1  A: 

This is not issue of Rails but rather AJAX / jQuery not sending Accept header: Try this:

$.ajax({
   url: 'url_to_action', dataType: "json",
     beforeSend : function(xhr){
       xhr.setRequestHeader("Accept", "application/json")
     },
     success : function(data){
       //.. do something with data
     },
     error: function(objAJAXRequest, strError, errorThrown){
       alert("ERROR: " + strError);
     }
  }
);

If all your AJAX requests expect JSON, then you can set header globally:

$.ajaxSetup({
  'beforeSend' : function(xhr){
    xhr.setRequestHeader("Accept", "application/json")
  } 
});

Other option would be adding .json to path or data:{format: 'json'} to $.ajax hash of options. Rails supports format path suffixes by default for resoures routing. Just try rake routes to see.

gertas
+1  A: 

You can set the Accept: application/json header for real REST, or you can add the format to the URL for quick hackery:

$.ajax({url: '/projects/yourprojects.json', dataType: 'json'});
Justice
that is awesome - and worked! wooow thank you. I couldn't find this anywhere on Google! I like the idea of using the accept, right now I have this on the top of my JS file ($.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")} })) .... Problem is some ajax request i need a .js response. others I want JSON. What's the smart way to handle this? Thanks!
WozPoz