简体   繁体   中英

Passing json from index action and rendering of another application layout simultaneously. Ruby on Rails

I have Vacancies controller and I need to pass @vacancies to json and also render another layout. The following code does not work (json is not passed however I have "wide" layout). If I remove format.html { render layout: "wide"} } json passes correctly. How to combine these two things?

class VacanciesController < ApplicationController
respond_to :html, :json
...
    def index
      @vacancies = Vacancy.all
      respond_with(@vacancies) do |format|
       format.html { render layout: "wide"} }
       format.json { render json: @vacancies } 
      end
     end
  ...

You can't call render twice, that's problem #1. You also can't send two responses to a single request.

There is also no purpose in rendering HTML (which means a fresh page load) and sending JSON (which is for AJAX requests, ie requests that don't reload the page) at the same time. It isn't possible, but it also would be pointless even if it was possible.

If you want to tell a request to use a specific layout, you can pass the layout option to a render call. However, a render call does not take a data object as the first argument, it takes a view name, or only an options hash. So to call this correctly you should use:

render :index, :layout => 'example'

I expect that will make your HTML views show up correctly.

Please understand however, the layout option is only useful for HTML responses, not JSON responses. Layout is telling your render call what outer HTML to wrap around the view your action is calling, and if you don't specify it uses 'application.html'

To help you understand one more thing: your respond block is telling the computer how to respond to different kinds of requests. It's like a switchboard. If you wrote it with if/else statements it might look like this:

if request_type == 'html'
  render :index, :layout => 'wide'
elsif request_type == 'json'
  render :json => @vacancies
else
  raise raise ActionController::UnknownFormat
end

So, with your respond_with block, if you fix your html render call, and assuming you're developing on localhost, if you enter the following URL in your browser and hit enter...

http://localhost:3000/vacancies

That would be making an HTML format GET request, which will load the page with layout: 'wide' but no other data. If you type:

http://localhost:3000/vacancies.json

That will simulate a JSON request, and you'll get just the JSON representation of the @vacancies data.

I hope that helps you solve your problem. If not, please describe what you're trying to accomplish in more detail so I can help you understand how to do it.

PS: one last tip: if you want to specify layouts at the controller level you can just call layout at the top of your controller, like so:

class ExampleController < ApplicationController
  layout 'awesome', :only => [:new,:edit]
  ...
end

This works like any other filter, you can pass :only, or :except, or no options at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM