2015-10-20 6 views
2

Я изучил существенную разницу между классом Ruby, методом экземпляра и основным различием, которое я нашел, так как нам не нужно создавать экземпляр этого класса, мы можем напрямую вызвать этот метод непосредственно из имени класса.Ruby on Rails instance vs class methods

class Notifier 

def reminder_to_unconfirmed_user(user) 
    headers['X-SMTPAPI'] = '{"category": "confirmation_reminder"}' 
    @user = user 
    mail(:to => @user["email"], :subject => "confirmation instructions reminder") 
    end 

end 

Итак, я определил метод экземпляра reminder_to_unconfirmed_user в моем Notifier классе, чтобы отправить электронную почту непроверенным пользователям, и когда я бегу Notifier.reminder_to_unconfirmed_user(User.last) это дозвонились при условии, что это метод экземпляра не метод класса.

+1

И в чем вопрос? – Meier

+0

Его вопрос в том, почему метод экземпляра можно вызвать в классе, как если бы он был методом класса. Добавлено ответ ниже. – bkunzi01

ответ

4

Чтобы определить метод класса, используйте self ключевое слово в определении метода (или имя класса):

class Notifier 
    def self.this_method_is_a_class_method 
    end 

    def Notifier.this_one_is_a_class_method_too 
    end 

    def this_method_is_an_instance_method 
    end 
end 

В вашем случае, reminder_to_unconfirmed_user должен быть определен как метод класса:

class Notifier 

    def self.reminder_to_unconfirmed_user(user) 
    # ... 
    end 

end 

Затем вы можете использовать его как это:

Notifier.reminder_to_unconfirmed_user(User.last) 
0

В вашем случае оно должно быть:

class Notifier 

    def self.reminder_to_unconfirmed_user(user) 
    headers['X-SMTPAPI'] = '{"category": "confirmation_reminder"}' 
    @user = user 
    mail(:to => @user["email"], :subject => "confirmation instructions reminder") 
    end 

end 

Как следует из их названия:

методы экземпляра на модели следует использовать для логики/операций, которые относятся к конкретному экземпляру модели (один на котором вызывается этот метод.)

Методы класса предназначены для вещей, которые не действуют на отдельный экземпляр модели или случаев, когда у вас нет экземпляра, доступного для вас. Как и в некоторых случаях, вы хотите применить изменения к нескольким группам объектов. Если вы хотите обновить всех пользователей в определенном состоянии, то вам следует перейти на метод класса.

Они имеют разный способ вызова:

class Test 
    def self.hi 
    puts 'class method' 
    end 

    def hello 
    puts 'instance method' 
    end 
end 

Foo.hi # => "class method" 
Foo.hello # => NoMethodError: undefined method ‘hello’ for Test:Class 

Foo.new.hello # => instance method 
Foo.new.hi # => NoMethodError: undefined method ‘hi’ for #<Test:0x1e871> 
0

я имел тот же вопрос, что ОП сделал и после того, как копаться я, наконец, понял это! Другие ответы, которые были рассмотрены только тогда, когда нужно использовать методы класса vs class в Ruby, однако Rails делает некоторые скрытые вещи за пределами возможностей. Вопрос заключался не в том, когда использовать методы экземпляра класса vs, а вместо того, как Rails позволяет вам вызвать метод экземпляра, как если бы это был метод класса, как показано в приведенном выше примере его почтовой программы. Это обусловлено: AbstractController::Base и их можно увидеть здесь: AbstractController::Base

В основном, во всех контроллерах (будь то ваша почтовая программа или стандартный контроллер), все определенные методы перехватываются «method_missing», а затем возвращает экземпляр этого класса ! Затем определенные методы также преобразуются в общедоступные методы экземпляра. Таким образом, поскольку вы никогда не создаете экземпляры этих классов (например, вы никогда не делаете Mailer.new.some_method), Rails автоматически вызывает method_missing и возвращает экземпляр этого Mailer, который затем использует все методы, определенные в этом классе.