Отключить макет для одного из действий

81

Моя ситуация: действие View в ReportsController должно отображать чистый html, но не как файл (чтобы просмотреть его в браузере и сохранить после этого). Поэтому для рендеринга я использую шаблон представления view.html.erb и не могу отключить любые макеты для этого действия. Но в других действиях этого контроллера макеты должны остаться нетронутыми. Работает только выключение для всего контроллера вот так:

ReportsController < ApplicationController
  layout false

Но что делаю неправильно :( для всех действий я пытался использовать что-то вроде этого в действии:

def view      
  @report = Report.new(params[:report])
  unless @report.valid?
    render :action => 'new' and return
  else
    render :layout => false     
  end   
end

Что я должен делать?

Антиархитектор
источник
Что ж, вам определенно не нужен этот явный возврат. Вы хотите, чтобы макет отображался, если отчет действителен?
tfwright

Ответы:

73

Попробуй это:

ReportsController < ApplicationController
  layout false
  layout 'application', :except => :view
Макид
источник
Похоже, что эта директива работает неправильно (или неожиданно). Я пробовал использовать несколько комбинаций этих параметров (: only,: except). Но странно сработало удаление всех макетов для всех действий. Я думаю, это из-за nil или false вместо layoutname. И система пытается использовать макеты «имя контроллера» для всех других действий, игнорируя макет приложения. Попробуйте поиграть с этими параметрами, и вы поймете, о чем идет речь.
Antiarchitect
2
Вы правы, :onlyне работает нормально layout nil. Однако мне удалось заставить его работать, обнулив макет и добавив его обратно с исключением. Я обновил свой ответ.
mckeed
2
Ответ Дэвида Ортиса «более правильный», поскольку он должным образом изолирует переключение макета на рассматриваемое одиночное действие.
Фрэнк Кёль,
Согласен с @Paul - falseработает! Спасибо за это!
mrstif 04
layout false, only: :viewкажется более лаконичным способом достижения той же цели без побочных эффектов, как упоминает Antiarchitect.
SMAG 05
116

Это должно сделать это,

def view
    ...
    render :layout => false
end

Ссылка на документацию

Дэвид Ортис
источник
Проблема в том, что вам придется указывать layout: falseдля каждого формата в действии.
JellicleCat
1
жизнь прекрасна, когда есть ответы! :-D
Педро Роло
11

В блоке ответа добавьте layout: false.

Например:

respond_to do |format|
  format.html { render :layout => false } # your-action.html.erb
end
Архонический
источник
2

Если вы хотите получить нестандартный шаблон без макета, вы можете использовать:

def non_rest
  render template: 'layouts/something_new', layout: false
end
Мугур 'Bud' Chirica
источник
Как насчет противоположного - могу ли я отрендерить макет по умолчанию без шаблона?
Qasim