2015-10-22 2 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 - это новый класс класса Derived класса Base в модуле ActionController. Что происходит в следующей строке? Is protect_from_forgery метод в базовом классе или в модуле ActionController? Как это называется? Я не смог найти документацию по рубинам. Я попытался создать метод в базовом классе, но получил ошибки, как показано ниже. Как создать такие специальные команды, которые можно использовать в классе?Что это за синтаксис внутри рубиновых кладов?

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

Это методы рельсов, а не рубины. Вот почему вы не можете их найти. [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

Его наследство. В вашем классе child вы можете использовать весь метод, наследуемый от класса 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

уверен, что, как я уже сказал, вам нужно вызвать методы экземпляра в экземпляре класса, на некоторый объект класса. Чтобы отказаться от этого подхода, я рекомендую вам ознакомиться с учебными пособиями ООП. Это довольно хорошо: 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 - это «метод класса» - метод, называемый самим классом.Попытка вызвать .greet на Greeter класса приведет к 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 

Возвращаясь к первоначальному вопросу, если вы заново класс Greeter, теперь вы можете использовать .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 
Смежные вопросы