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

Почему в рубине/рельсах/activerecord нет необходимости всегда?

При тестировании пары геттер/сеттер в модели рельсов я нашел хороший пример поведения, которое я всегда считал нечетным и непоследовательным.

В этом примере я имею дело с class Folder < ActiveRecord::Base.

Folder belongs_to :parent, :class_name => 'Folder'

В методе getter, если я использую:

def parent_name
  parent.name
end

... или...

def parent_name
  self.parent.name
end

... результат точно такой же, я получаю имя родительской папки. Однако в методе геттера, если я использую...

def parent_name=(name)
  parent = self.class.find_by_name(name)
end

... parent становится nil, но если я использую...

def parent_name=(name)
  self.parent = self.class.find_by_name(name)
end

... тогда он работает.

Итак, мой вопрос: зачем вам иногда объявлять self.method и почему вы можете просто использовать локальную переменную?

Кажется, что необходимость/использование self в ActiveRecord противоречива, и я хотел бы понять это лучше, поэтому я не чувствую, что я всегда предполагаю, нужно ли объявлять себя или нет. Когда вы/не должны ли вы использовать self в моделях ActiveRecord?

4b9b3361

Ответ 1

Это потому, что атрибуты/ассоциации - это фактически методы (getters/seters), а не локальные переменные. Когда вы указываете "parent = value", Ruby предполагает, что вы хотите присвоить значение родительской переменной.

Где-то в стеке есть метод setter "def parent =" и для вызова того, что вы должны использовать "self.parent =", чтобы сообщить ruby, что вы действительно хотите вызвать setter, а не просто установить локальную переменную.

Когда дело доходит до геттеров, Ruby смотрит, есть ли первая локальная переменная, и если ее не удается найти, она пытается найти метод с тем же именем, поэтому ваш метод getter работает без "я".

Другими словами, это не ошибка Rails, но это то, как Ruby работает по своей сути.

Надеюсь, что это поможет.