Rails controller displays JSON in browser

I have a simple controller that I respond with both html and json . I am using json answer for Backbone application. Everything works as expected, except that when I click the link using the show method and then click the back button, the index method simply prints a large json string in the browser. If I update, it displays HTML as expected. Here is the controller.

 class RecipesController < ApplicationController def index @user = User.find(params[:user_id]) @recipes = Recipe.all respond_to do |format| format.html format.json { render json: Recipe.where(user_id: params[:user_id]).featured } end end ... end 

I tried adding a check for response.xhr? and only json rendering if it was an AJAX request, but that didn't work.

Edit

This is a Rails 3 application that does not use turbolinks.

Edit 2

Here is the corresponding baseline code.

 # app/assets/javascripts/collections/recipe_list_.js.cofee @App.Collections.RecipeList = Backbone.Collection.extend url: -> "/users/#{@userId}/recipes" model: window.App.Models.Recipe initialize: (opts) -> @userId = opts.userId # app/assets/javascripts/app.js.coffee $ -> urlAry = window.location.href.split('/') userId = urlAry[urlAry.length - 2] App = window.App App.recipeList = new App.Collections.RecipeList(userId: userId) App.recipeListView = new App.Views.RecipeListView 
+7
json ruby-on-rails
source share
4 answers

you can try using /recipes.html and / recipes.json and / recipes / 1.html and / recipes / 1.json

instead of relying on highway and history to always send the right headers

+2
source share

If you mean the problem with chrome and turbolinks, then it is easy to eliminate caching with ajax requests:

$.ajaxSetup({cache: false})

+4
source share

I bet because of a turbo link or ajax based page rendering (backbone, remote=true , ...)

I always turned off turbolink and control which links are remote=true , and for all ajax answers I insert this javascript line at the end

 history.pushState(null, '', '/the/requested/url' ); 

If you do not want to manually implement this line for each of your responses to links, you can wrap it in the ajax:complete event ( more information ), and I assume that the turbine has an event that you can also use.

The second part of the trick is to popstate , so when your users click the back button, the page will be refreshed from the server (via the URL that was previously pushState-ed) and ajax / js / json / any answer is no longer will be displayed.

 setTimeout( function () { $(window).bind('popstate', function () { window.location = location.href; }); }, 500); 

As you can see, I am wrapping the binding of the popstate event in setTimeout , because if you do not, you might have problems with some browsers that will endlessly refresh the page.

+3
source share

Are you using Chrome? if so known problem. When you press the back button, the chromes serve the page from the cache, since the return was json, this is what it resets on the screen. There are some recommended workarounds in this post.

https://code.google.com/p/chromium/issues/detail?id=108766

+2
source share

All Articles