Условное расположение и кэширование действий без размещения - PullRequest
3 голосов
/ 04 марта 2012

У меня есть действие на контроллере, где я использую кеширование действий. Однако я использую флаг layout: false для этого кеширующего вызова, так как мой макет содержит информацию, зависящую от пользователя, например, статус входа. Это отлично работает.

Затем я добавил гем pjax-rails, который в основном добавляет этот код в контроллер:

layout ->(c) { pjax_request? ? false : 'application' }

То есть по некоторым запросам макет не отображается. Теперь я (как бы логично) хочу объединить эти два подхода вместе.

Однако, когда pjax_request? == true я получаю эту ошибку:

Не было макета по умолчанию для MyController

Что я делаю не так и как я могу решить эту проблему?


PS: в данном случае это легче всего воспроизвести:

class MyController < ApplicationController
  layout false
  caches_action :index, :layout => false

  def index
  end
end

Ответы [ 3 ]

2 голосов
/ 07 марта 2012

Я почти думаю, что это может быть ошибка в Rails.Проверьте этот блок кода в строке 143 actionpack/lib/action_controller/caching/actions.rb:

body = controller.read_fragment(cache_path.path, @store_options)

unless body
  controller.action_has_layout = false unless @cache_layout
  yield
  controller.action_has_layout = true
  body = controller._save_fragment(cache_path.path, @store_options)
end

body = controller.render_to_string(:text => body, :layout => true) unless @cache_layout

controller.response_body = body

Похоже, что он правильно отображает тело без макета в первом блоке unless, но затемон заставляет шаблон отображать с макетом как частью тела ответа.И если вы посмотрите на трассировку стека, это строка, которая приводит к исключению.

Я вручную отредактировал файл в :layout => @cache_layout (который всегда оценивается в :layout => false, поскольку он защищен unless)и представление отображается так, как ожидалось.

Я не уверен, что вы могли бы сделать с этим, кроме как временно исправить этот файл самостоятельно и открыть отчет об ошибке.Я также могу ошибаться в отношении поведения этой строки, но она определенно выглядит как виновник.

1 голос
/ 21 января 2013

Для тех, кто сталкивается с этим в будущем, начиная с рельсов 3, установка макета по умолчанию для контроллера:

layout "application"

http://apidock.com/rails/AbstractController/Layouts/ClassMethods/layout

Кажется, чтобы преодолеть эту проблему, это действительно дефект рельсов.

0 голосов
/ 19 февраля 2014

Я также хотел предложить решение, если вы сделаете это, оно решит вашу проблему:

layout Proc.new {|controller|
  controller.action_has_layout = false
  false
}

Просто заставляет action_has_layout из ответа @ Брендана

...