将初始化打破rails中的布局设置?

Vic*_*Lam 17 layout initialization ruby-on-rails

在其中一个控制器中,我需要一个特定的布局.我layout在开头添加了.它运作良好.

但是,如果我initialize为一些基于控制器的变量添加一个函数.Rails似乎只是忽略了layout命令.

有没有人有同样的问题?我该如何解决?

class AdminsController < ApplicationController

  layout "layout_admins"

  def initialize
    @Title = "Admins"
  end

  def index
    ....... some code here
  end
end
Run Code Online (Sandbox Code Playgroud)

Rya*_*igg 32

initialize在内部用于Rails,以及初始化控制器的新实例,以便它可以在其上提供请求.通过以这种特定方式定义此方法,您将破坏Rails.

有办法通过!隧道尽头的一盏灯.彩虹尽头的一罐金子:

def initialize
  @title = "Admins"
  super
end
Run Code Online (Sandbox Code Playgroud)

看到那里的小super电话?那将调用超类的initialize方法,正如Rails所做的那样.现在我们已经介绍了如何按照自己的方式进行操作,让我们来介绍如何使用"官方认可的"Rails方式:

class AdminsController < ApplicationController
  before_filter :set_title


  # your actions go here

  private      
    def set_title
      @title = "Title"
    end
end
Run Code Online (Sandbox Code Playgroud)

是的,这是一个更多的代码,但它会减少其他注视代码的人的挫败感.这是传统的做法,我强烈鼓励遵循惯例,而不是做"魔术".

编辑:如果您使用Rails 5,那么您将需要使用before_action而不是before_filter.

  • 在初始化器中调用super并不神奇 - 这是正确的编程实践.不过,你的回答是正确的 (3认同)

EmF*_*mFi 6

我不确定它究竟是如何layout发挥作用的,但是我愿意在ActionController #initialize方法的一个yield块中打赌它.因此,重写初始化可以解释问题.

看起来你在这里有太多的选择:

  1. 用super关闭你的新定义来调用ActionController初始化,它应该使用类中定义的布局.

    例如:

    def initialize
      @Title = "Admins"
      super
    end
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用before过滤器初始化变量.这是在控制器中初始化值的Rails方法

    class AdminsController < ApplicationController
      layout "layout_admins"
    
    
      before_filter :set_title
      def set_title
        @Title = "Admins"
      end
    
    
      def index
        ....... some code here
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)