Как передать переменную в макет? - PullRequest
12 голосов
/ 12 сентября 2011

У меня есть две версии моего макета приложения, которые отличаются только несколькими строками. Рассмотрим следующий пример:

!!!    
%html
    %head
        # a lot of code here
%body
    # some more code here
    - if defined? flag and flag == true
        # variant 1
    - else
        # variant 2

Вопрос в том, как передать этот флаг макету?

class ApplicationController < ActionController::Base
    layout 'layout', :locals => {:flag => true} #won't work :(

    # ...
end

Ответы [ 5 ]

16 голосов
/ 12 сентября 2011

Я обычно предпочитаю использовать вспомогательные методы вместо переменных экземпляра в этих ситуациях.Вот пример того, как это можно сделать:

class ApplicationController < ActionController::Base
  layout 'layout'
  helper_method :flag

  ...

protected
  def flag
    true
  end
end

И если у вас есть контроллер, флаг которого не должен быть истинным, вы просто перезаписываете метод:

class PostsController < ApplicationController
  ...

private
  def flag
    false # or perhaps do some conditional
  end
end

Таким образомвы убедитесь, что помощник по флагам всегда доступен в представлениях, поэтому вам не нужно делать if defined? или что-либо еще, а также, в случаях, когда не используется макет, тогда никакая переменная экземпляра не назначается ни в одном before_filter.

Это также помогает сохранить как можно меньше переменных экземпляра в представлениях.

13 голосов
/ 12 сентября 2011

Хорошо, поэтому я нашел решение самостоятельно:

class ApplicationController < ActionController::Base
    layout 'layout'
    before_filter :set_constants

    def set_constants
        @flag = true
    end
end

И шаблон должен быть:

!!!    
%html
    %head
        # a lot of code here
%body
    # some more code here
    - if @flag
        # variant 1
    - else
        # variant 2
8 голосов
/ 15 июля 2013

Существует еще два варианта , которые фактически задает ОП:

# 1

в вашем макете:

- if flag ||= false
  # variant 1
- else
  # variant 2

в вашем контроллере приложения (это хитрость):

layout 'application' # or whatever

в любом контроллере:

render :locals => { :flag => true }

Я думаю, обработка макета происходит позже из-за "динамическое "(не совсем) layout определение, которое генерирует необходимые методы для всех ключей внутри local_assigns.Поэтому, возможно, переменная экземпляра является решением исполнителяЕсть мысли по этому поводу?Пожалуйста, оставьте комментарий.

# 2

Вы можете просто использовать переменную local_assigns, например:

- if local_assigns[:flag] ||= false
  # variant 1
- else
  # variant 2

и затем в любом из ваших контроллеров:

render :locals => { :flag => true }
8 голосов
/ 12 сентября 2011

Переменная экземпляра контроллера?Это нормальный способ получения информации для шаблона.

0 голосов
/ 12 сентября 2011

А как насчет http://snippets.dzone.com/posts/show/236 для условного выбора макетов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...