Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails controller renders JSON in browser

I have a simple controller that I have responding to both html and json. I'm using the json response for a Backbone app. Everything works as expected, except that when I click a link that uses the show method, and then click the back button, the index method just prints a big string of JSON into the browser. If I refresh, it displays HTML as expected. Here's 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 rendering JSON if it was an AJAX request, but that didn't work.

Edit

This is a Rails 3 app not utilizing turbolinks.

Edit 2

Here is the relevant Backbone 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
like image 987
nickcoxdotme Avatar asked Oct 23 '14 14:10

nickcoxdotme


People also ask

What does render JSON do in Rails?

By using render json: in our Rails controller, we can take entire models or even collections of models, have Rails convert them to JSON, and send them out on request.

How can you tell Rails to render without a layout?

By default, if you use the :plain option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option and use the . text. erb extension for the layout file.

How do you render a partial?

Rendering a Partial View You can render the partial view in the parent view using the HTML helper methods: @html. Partial() , @html. RenderPartial() , and @html.

What are partials Ruby?

A partial allows you to separate layout code out into a file which will be reused throughout the layout and/or multiple other layouts. For example, you might have a login form that you want to display on 10 different pages on your site.


2 Answers

If you're referring to a chrome and turbolinks issue, then an easy fix is to disable caching on ajax requests:

$.ajaxSetup({cache: false})

like image 198
Yossi Shasho Avatar answered Oct 21 '22 16:10

Yossi Shasho


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

instead of relying on backbone and history to always send the correct headers

like image 26
somedude Avatar answered Oct 21 '22 15:10

somedude