Почему в рубине/рельсах/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?
Ответы
Ответ 1
Это потому, что атрибуты/ассоциации - это фактически методы (getters/seters), а не локальные переменные. Когда вы указываете "parent = value", Ruby предполагает, что вы хотите присвоить значение родительской переменной.
Где-то в стеке есть метод setter "def parent =" и для вызова того, что вы должны использовать "self.parent =", чтобы сообщить ruby, что вы действительно хотите вызвать setter, а не просто установить локальную переменную.
Когда дело доходит до геттеров, Ruby смотрит, есть ли первая локальная переменная, и если ее не удается найти, она пытается найти метод с тем же именем, поэтому ваш метод getter работает без "я".
Другими словами, это не ошибка Rails, но это то, как Ruby работает по своей сути.
Надеюсь, что это поможет.