红宝石类声明问题

时间:2010-07-13 00:52:32

标签: ruby-on-rails ruby

在红宝石中你可以拥有:

class ApplicationController < ActionController::Base
  before_filter :require_login
end

我只是想知道什么是before_filter?它是ActionController :: Base的一个方法吗?

如果我创建ApplicationController的对象会发生什么? before_filter方法将运行吗?

谢谢!

4 个答案:

答案 0 :(得分:8)

是的,before_filter是ActionController :: Base上的一个方法。 before_filter中指定的任何内容都将在被调用的操作之前运行。

API文档:http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html#M000316

编辑:

直接写入类时,在将类加载到解释器时执行该代码。

将此输入IRB:

>> class Hello
>> p "hello"
>> end
"hello"

所以在你提到的情况下,ruby会看到before_filter方法并试图找到它。它开始查看它的类,然后它进入父类和父类的父类,依此类推,直到它到达Object。在这种情况下,它将转到ActionController :: Base类并查找before_filter,然后查找链到类,模块和对象。

>> ActionController::Base.class
=> Class
>> ActionController::Base.class.superclass
=> Module
>> ActionController::Base.class.superclass.superclass
=> Object
>> ActionController::Base.class.superclass.superclass.superclass

如果您正在阅读,我强烈推荐MetaProgramming Ruby,它可以更好地解释对象模型。

答案 1 :(得分:3)

在类定义中执行方法时,实际上是这样做的:

class ApplicationController
  self.before_filter
end

当self是类对象本身时(例如,在类定义中尝试puts self

例如,定义过滤器的穷人方式是

class Filterable

    @@filters = []

    def self.before_filter(method_name)
      @@filters << method_name
    end

    def self.filters
      @@filters
    end

    def some_important_method
      self.class.filters.each do |method_name|
        # Halt execution if the return value of one of them is false or nil
        return unless self.send(method_name)
      end
      puts "I'm in some important method"
      # Continue with method execution
    end

end

class SomeClass < Filterable

  before_filter :first_filter
  before_filter :second_filter

  attr_accessor :x

  def initialize(x)
    @x = x
  end

  def first_filter
    puts "I'm in first filter"
    true
  end

  def second_filter
    puts "I'm in second filter"
    @x > 5
  end

end

你可以测试它

SomeClass.new(8).some_important_method
# => I'm in first filter
#    I'm in second filter
#    I'm in some important method

SomeClass.new(3).some_important_method
# => I'm in first filter
#    I'm in second filter

希望它澄清

答案 2 :(得分:2)

重要的是要知道,在ruby中,类声明中的代码不是“特殊的”。

这只是常规代码。您不仅限于定义方法和类变量 - 您的代码几乎可以做任何事情。

例如,你可以做这样的事情:

class MyClass
  print "wow"
end

结束后,打印“哇”并返回nil。

我再说一遍:你可以在类定义中包含你想要的任何东西。 包括调用类本身的调用方法

这正是before_filter的作用。它修改了类,其方式是“在调用此类的任何方法之前,必须自动调用require_login”。

答案 3 :(得分:0)

link解释得非常好。基本上Ruby允许使用语法“糖”,允许您定义将在特定时间运行的ruby代码块。在before_filter情况下,它将在任何操作方法之前运行。