Как называются обратные вызовы? - PullRequest
0 голосов
/ 27 апреля 2018

Какова среда обратного вызова?

Например, в листинге 6.20 стандартного учебника по Ruby on Rails "(http://rails -4-0.railstutorial.org / book / modelling_users ) он имеет:

class User < ActiveRecord::Base
  before_save { self.email = email.downcase }

Откуда приходит электронная почта? мы находимся в функции, где определено email? или на самом деле @email?

Кроме того, есть ли важная причина, по которой мы используем self.email вместо @email (или просто email, если он совпадает с @email)? или это просто стилистический или педагогический?

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Обратные вызовы выполняются в области объекта (пользователя в вашем примере). self.email= - это метод объекта, а @email - переменная экземпляра.

ActiveRecord автоматически создает методы (методы получения и установки) для всех столбцов в соответствующей таблице базы данных (я предполагаю, что в таблице users имеется столбец email).

Обратите внимание, что использование @email = вместо self.email = создаст переменную экземпляра и не обновит столбец в базе данных.

0 голосов
/ 27 апреля 2018

Здесь происходит несколько вещей одновременно:

  1. Блок вызывается в контексте сохраняемого экземпляра модели, поэтому self в блоке является сохраняемым User. Блок также получает аргумент, но вам не нужно его использовать.
  2. Локальные переменные в Ruby не объявляются явно, они неявно объявляются при первой попытке дать им значение.
  3. Неявный получатель для вызовов методов: self.
  4. Но локальные переменные имеют приоритет над вызовами методов, поэтому метод-мутатор (например, self.email=) нуждается в явном приемнике, чтобы отличать его от локальной переменной.
  5. Переменные экземпляра (@email) не имеют ничего общего с атрибутами в моделях ActiveRecord.
  6. Метод доступа (self.email или просто email, если нет локальной переменной email) и методы мутатора (self.email=) для объектов ActiveRecord работают с атрибутами, а не с переменными экземпляра.

Итак, это:

before_save { self.email = email.downcase } # (1)

также можно записать как:

before_save { |user| user.email = user.email.downcase } # (2)

или даже:

before_save { |user| user.send(:email=, user.send(:email).downcase) } # (3)

Основное функциональное отличие состоит в том, что (2) требует, чтобы методы email и email= были общедоступными.

...