Ответ 1
Из Rails guide, 2.2.13.2 Choosing Layouts at Runtime
:
class ProductsController < ApplicationController
layout :products_layout
private
def products_layout
@current_user.special? ? "special" : "products"
end
end
Возможно ли reset макет по умолчанию из метода before_filter в Rails 3?
У меня есть следующее: contacts_controller.rb:
class ContactsController < ApplicationController
before_filter :admin_required, :only => [:index, :show]
def show
@contact = Contact.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @contact }
end
end
[...]
end
И следующее в моем application_controller.rb
class ApplicationController < ActionController::Base
layout 'usual_layout'
private
def admin_required
if !authorized? # please, ignore it. this is not important
redirect_to[...]
return false
else
layout 'admin' [???] # this is where I would like to define a new layout
return true
end
end
end
Я знаю, что могу просто поставить...
layout 'admin', :only => [:index, :show]
... сразу после "before_filter" в "ContactsController", но, поскольку у меня уже есть множество других контроллеров со многими действиями, которые были отфильтрованы как требуемые администратором, было бы намного легче, если бы я мог просто reset макет от "обычного_layout" до "admin" внутри метода "admin_required".
Кстати, поместив...
layout 'admin'
... внутри "admin_required" (как я пытался в коде выше), я получаю сообщение об ошибке метода undefined. Кажется, он работает только за пределами defs, так же, как я сделал для "обычного_layout".
Спасибо заранее.
Из Rails guide, 2.2.13.2 Choosing Layouts at Runtime
:
class ProductsController < ApplicationController
layout :products_layout
private
def products_layout
@current_user.special? ? "special" : "products"
end
end
Если по какой-либо причине вы не можете изменить существующий контроллер и/или просто хотите сделать это в переднем фильтре, который вы можете использовать self.class.layout :special
, вот пример:
class ProductsController < ApplicationController
layout :products
before_filter :set_special_layout
private
def set_special_layout
self.class.layout :special if @current_user.special?
end
end
Это просто еще один способ сделать то же самое. Больше возможностей для более счастливых программистов!
Современный способ сделать это - использовать proc,
layout proc { |controller| user.logged_in? "layout1" : "layout2" }