Ответ 1
Переменная экземпляра контроллера? Это нормальный способ получения информации в шаблон.
У меня есть две версии моего макета приложения, которые отличаются только несколькими строками. Рассмотрим следующий пример:
!!!
%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
Переменная экземпляра контроллера? Это нормальный способ получения информации в шаблон.
Обычно я предпочитаю использовать вспомогательные методы вместо переменных экземпляра в этих ситуациях. Вот пример того, как это можно сделать:
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
.
Он также помогает хранить как можно меньше переменных экземпляра в представлениях.
Хорошо, поэтому я нашел решение самостоятельно:
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
Существует еще два варианта, что на самом деле запросил OP:
в вашем макете:
- if flag ||= false
# variant 1
- else
# variant 2
в вашем прикладном контроллере (это трюк):
layout 'application' # or whatever
в любом контроллере:
render :locals => { :flag => true }
Я предполагаю, что обработка макета происходит позже из-за "динамического" (не реально) определения layout
и генерирует необходимые методы для всех ключей внутри local_assigns
. Так что, возможно, переменная экземпляра является решением для исполнителей. Любые мысли об этом? Пожалуйста, оставьте комментарий.
Вы можете просто использовать переменную local_assigns
, например:
- if local_assigns[:flag] ||= false
# variant 1
- else
# variant 2
а затем в любом из ваших контроллеров:
render :locals => { :flag => true }
Как насчет http://snippets.dzone.com/posts/show/236, чтобы условно выбрать макеты?