Подтвердить что ты не робот

Почему обратные вызовы ActiveRecord требуют, чтобы переменные экземпляра или методы экземпляра имели префикс с ключевым словом self?

ActiveRecord имеет несколько различных методов обратного вызова, используемых для упрощения логики модели. Например, методы after_find и before_create.

Рассмотрим этот пример кода:

class ExternalPrintingCard < ActiveRecord::Base
  belongs_to :user
  belongs_to :ph_user

  after_create :change_pin

  def change_pin
    self.user.randomize_printer_pin
  end

  def after_find
    return if self.card_status == false
    self.card_status = false if self.is_used_up?
    self.card_status = false if self.is_expired?
    self.save!
  end
end

Если я удалю все префиксы self из переменных экземпляра или методов экземпляра, эти вызовы будут вызваны, но они как локальные переменные внутри этих методов обратного вызова.

Эта переменная экземпляра (card_status), методы экземпляра (save!, is_used_up? и is_expired?) и ассоциация (user) отлично работали за пределами этих двух методов обратного вызова без префикса self.

Пример кода в документации Rails для методов обратного вызова (методы экземпляра), по-видимому, всегда использует префикс self, даже если он вызывает экземпляры или методы экземпляра, которые по праву они доступны без префикса self в нормальном режиме.

Я надеюсь, что кто-то, кто лучше понимает обратные вызовы ActiveRecord, может помочь пролить свет на это поведение.

Приветствия

4b9b3361

Ответ 1

Технически вам нужно использовать только себя перед методами назначения. Это необходимо для разграничения между методом экземпляра с trailing = и назначением локальной переменной.

Ответ 2

Насморн прав.

ActiveRecord:: Base помещает все имена столбцов внутри переменной экземпляра @attributes (Hash) и создает методы экземпляров-экземпляров для этих имен столбцов.

Например:

card_status - это столбец в таблице external_printing_cards, он будет иметь методы доступа с именем card_status и card_status=

Так как определение локальной переменной ruby ​​является динамическим, строка

def after_find
  ....  
  card_status = false if self.is_used_up?
  ....
end

будет означать, что мы определяем и присваиваем локальной переменной card_status, а не метод экземпляра card_status=

В статье, которую опубликовал Peer Allan, содержится больше объяснений.