2015-10-22 30 views
4
class ApplicationController < ActionController::Base 
    protect_from_forgery #What is this syntax? When is this executed and how to create one? 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 
    attr_accessible :body, :commenter, :post 
end 

在第一种情况下,我了解ApplicationController是模块ActionController中新的Derived类,名为Base。下一行会发生什么? protect_from_forgery是基类还是模块ActionController中的方法?这叫什么?我无法在Ruby类文档中找到。我尝试在基类中创建一个方法,但得到如下错误。我如何创建可以在课堂上使用的特殊命令?ruby​​ clases里面的语法是什么?

class Base 
    def foo 
    @name = "foo" 
    end 
end 

class Der < Base 
    foo 
    def bar 
    @dummy = "bar" 
    end 
end 

错误:

expr1.rb:62:in `<class:Der>': undefined local variable or method `foo' for Der:Class (NameError) 
    from expr1.rb:61:in `<main>' 
+0

那些是rails方法,而不是ruby。这就是为什么你找不到它们。 [forgery_protection](http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html)。这是[ActionController]中的类方法(https://github.com/rails/rails/blob/e7feaff70f13b56a0507e9f4dfaf3ebc361cb8e6/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L102) –

+0

@japed如何创建此类方法?何时执行?为什么我的例子不起作用? – balki

回答

3

protect_from_forgery是在一个模块中定义一个类的方法包括在ActionController::Base并提供给孩子上课的时候你从ActionController::Base继承。

Rails中的这种方法有时被称为“宏”,因为它们是启用某些特定功能的类方法(有时也使用元编程来定义额外的方法或帮助程序)。实际上,由于Ruby没有宏,因此术语“宏”是不正确的。他们不是别的,而是类方法。

要记住的最重要的细节是,它们在类定义中使用时。这些方法在代码评估中运行,而不是在运行时运行。

class Base 
    def foo_instance 
    p "foo instance" 
    end 

    def self.foo_class 
    p "foo class" 
    end 
end 

class Der < Base 
    foo_class 
    def bar 
    p "bar" 
    end 
end 

Der.new.bar 

会产生

"foo class" 
"bar" 
-2

它继承。在你的孩子课堂中,你可以使用从parrent课程中得到的所有方法。 首先,您可以调用类实例的方法。 在您的例子,你可以做某事像这样:

base_object = Base.new 
    base_object.foo 

    der_object = Der.new 
    der_object.bar 

也得益于继承,你可以做某事像这样:

der_object.foo 

下面是简单教程红宝石继承举例: http://rubylearning.com/satishtalim/ruby_inheritance.html

快乐编码!

+0

你能解释为什么我会引用错误吗? – balki

+0

当然,正如我所说的,你需要在类的实例上调用一些类对象上的实例方法。为了解决这个问题,我建议你阅读一些OOP教程。这个很好:http://www.tutorialspoint.com/ruby/ruby_object_oriented.htm – gajewsky

1

要创建类方法,您可以执行其中任何一种。

class Base 
    def self.foo 
    end 
end 

class Base 
    class << self 
    def foo 
    end 
    end 
end 

因为他们是类方法,你叫他们在类

Base.foo

1

所以,你说什么是“类方法” - 类的方法是被用于该类本身定义的方法,而不是通过类的实例 。请注意以下几点:

class Greeter 
    def initialize(name) 
    @name = name 
    end 

    def greet 
    "hello, #{@name}" 
    end 
end 

Greeter.new("bob").greet # => "hello, bob" 

#greet是在Greeter类的一个实例方法。然而,.new是一个“类方法” - 这是一个方法本身调用的方法。试图调用.greetGreeter类将导致NameError

Greeter.greet # ! NameError 

所以,如果要定义这样一个“类方法”,你必须使用以下语法之一:

class Greeter 
    def self.greet(name) 
    "hello, #{name}" 
    end 

    class << self 
    def greet(name) 
     "hello, #{name}" 
    end 
    end 

    class << Greeter 
    # same as above 
    end 
end 

def Greeter.greet(name) 
    "hello, #{name}" 
end 

让我们回到原来的问题,如果你重新打开迎宾类,你现在可以使用.greet方法:

class Greeter 
    greet "bob" # => "hello, bob" 
end 

这也适用于子类,还有:

class Host < Greeter 
    greet "bob" # => "hello, bob" 
end 

这是Rails的是如何提供这些方法 - 它们定义在基类的类方法,最常见的ActiveRecord::Base,然后你就可以使用 - 解释方法,如protect_from_forgery

1

protect_from_forgery是一个类的方法:看起来是这样的

def protect_from_forgery(options = {}) 
     self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session) 
     self.request_forgery_protection_token ||= :authenticity_token 
     prepend_before_action :verify_authenticity_token, options 
     append_after_action :verify_same_origin_request 
     end 

因此,它通过应用控制器继承:

class ApplicationController < ActionController::Base 

你的例子可以这样写:

class Base 
    class << self 
    def foo 
     @name = "foo" 
    end 
    end 
end 

class Der < Base 
    foo  #class method from Base 
    def bar 
    @dummy = "bar" 
    end 
end 

查看foo的值

Der.foo.inspect