Rails在before_filter方法中设置布局

gui*_*ato 20 layout ruby-on-rails before-filter

是否可以在Rails 3中的before_filter方法中重置默认布局?

我有以下作为我的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
Run Code Online (Sandbox Code Playgroud)

以及我的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
Run Code Online (Sandbox Code Playgroud)

我知道我可以放......

layout 'admin', :only => [:index, :show]
Run Code Online (Sandbox Code Playgroud)

... ...在"ContactsController"中的"before_filter"之后,但是,由于我已经有许多其他控制器正确地被过滤为管理员要求的操作,如果我可以重置布局" "admin_required"方法中的ordinary_layout"to"admin".

顺便说一下,放......

layout 'admin'
Run Code Online (Sandbox Code Playgroud)

...在"admin_required"里面(正如我在上面的代码中尝试的那样),我得到一个未定义的方法错误消息.它似乎只在defs之外工作,就像我为"ordinary_layout"所做的那样.

提前致谢.

apn*_*ing 68

Rails指南,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
Run Code Online (Sandbox Code Playgroud)


Sch*_*ems 18

如果由于某种原因你无法修改现有的控制器和/或只是想在之前的过滤器中执行此操作,您可以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
Run Code Online (Sandbox Code Playgroud)

这只是做同样事情的另一种方式.更多选择让更快乐的程序员!

  • 我遇到的这个方法遇到的一个大问题是,Rails缓存了布局,因此即使它不应该也可以应用.线程安全或其他一些.使用`layout:set_layout`和`def set_layout`方式,更安全:) (12认同)