2015-10-22 61 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