我有Vacations控制器,我需要将@vacations传递到json,并呈现另一个布局。下面的代码不起作用(json没有被传递,但是我有"宽"布局)。如果我删除format.html{render layout:"wide"}}json正确通过。如何将这两件事结合起来?
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
...
不能调用render两次,这是问题1。您也不能对一个请求发送两个响应。
同时呈现HTML(意味着新的页面加载)和发送JSON(用于AJAX请求,即不重新加载页面的请求)也是没有目的的。这是不可能的,但即使有可能,这也毫无意义。
如果要告诉请求使用特定布局,可以将布局选项传递给渲染调用。但是,呈现调用不将数据对象作为第一个参数,而是使用视图名称或仅使用选项哈希。因此,要正确地调用它,您应该使用:
render :index, :layout => 'example'
我希望这将使您的HTML视图正确显示。
但是,请理解,布局选项仅适用于HTML响应,而不适用于JSON响应。Layout告诉您的呈现调用要在您的操作调用的视图周围包裹什么外部HTML,如果您没有指定,则使用"application.HTML"
为了帮助你理解另一件事:你的响应块告诉计算机如何响应不同类型的请求。它就像一个交换机。如果你用If/else语句写它,它可能看起来像这样:
if request_type == 'html'
render :index, :layout => 'wide'
elsif request_type == 'json'
render :json => @vacancies
else
raise raise ActionController::UnknownFormat
end
因此,对于responsd_with块,如果您修复了html渲染调用,并且假设您在localhost上进行开发,如果您在浏览器中输入以下URL并点击enter。。。
http://localhost:3000/vacancies
这将产生一个HTML格式的GET请求,该请求将加载带有layout: 'wide'
但没有其他数据的页面。如果您键入:
http://localhost:3000/vacancies.json
这将模拟一个JSON请求,您将只得到@vacancies
数据的JSON表示。
我希望这能帮助你解决问题。如果没有,请更详细地描述你试图实现的目标,这样我可以帮助你了解如何做到
附言:最后一个提示:如果你想在控制器级别指定布局,你可以在控制器顶部调用layout
,就像这样:
class ExampleController < ApplicationController
layout 'awesome', :only => [:new,:edit]
...
end
这与任何其他过滤器一样工作,您可以传递:only、或:except或根本不传递任何选项。