attr_accessor - метод уровня класса. Вы пытаетесь использовать его на уровне экземпляра.
Попробуйте вместо cattr_accessor
. Хотя вам не нужны attr_accessor
или cattr_accessor
для доступа к атрибутам модели ActiveRecord::Base
, которые определены в схеме.
====> РЕДАКТИРОВАТЬ <==== Исправленный ответ ниже </h2>
Не обращайте внимания на совет выше. Это не точно. Я оставляю это для справки. Причина, по которой вы получаете ошибку undefined method: name
, заключается в том, что вы установили attr_accessor
для модели, в которой уже установлен динамический метод получения с помощью ActiveRecord::Base
.
Установка attr_accessor
для атрибута столбца БД моделей ActiveRecord::Base
вызывает некоторый конфликт. Когда вы удаляете метод attr_accessor
и вместо этого добавляете то, что должно быть его точным эквивалентом ...
def name
name
end
и затем попытайтесь вызвать, что вы получаете бесконечно рекурсивный цикл вашего вызова, потому что метод получения .name
, который мы определили выше, вызывает сам себя и не обращается к методу получения ActiveRecord, который фактически извлекает данные из вашей БД.
Я предполагаю, что каким-то образом классы модели active_record просто выдадут вам ошибку undefined method
, а не сделают рекурсивный вызов, который заканчивается ошибкой stack level too deep
.
Однако, поскольку вы не получаете ошибку stack too deep
, мое следующее предположение состоит в том, что определенный вами attr_accessor
переопределяет динамически созданный метод получения ActiveRecord::Base
, пока rails все еще пытается получить доступ к переопределенному методу (который больше не существует). Возможно, это приведет к ошибке undefined method 'name'
.
Но ...
Когда вы добавляете свой собственный метод получения таким образом ... тогда он работает ...
def name
super
end
это потому, что с super
ваш класс просто наследует поведение своего динамически определенного метода получения ActiveRecord::Base
. Вы можете проверить это, добавив ...
def name
super
'Foo'
end
И когда вы позвоните @model.name
, вы увидите, что Foo
возвращается. Удалите 'Foo' из метода, и вам возвращается super
вызов динамически создаваемого метода ActiveRecord::Base
getter.
Я открыт для правок и внесу свой вклад в этот ответ. Это мой логический вывод из тестирования в моей консоли и чтения.
Когда использовать attr_accessor
Также, чтобы ответить на ваш вопрос о том, когда использовать attr_accessor
...
Это можно использовать, когда вы хотите создавать и хранить информацию, которая является бизнес-логикой, а также связана с моделью и длится только в течение жизненного цикла запроса / экземпляра.
Например, необработанные пароли (хотя я недоволен тем, кто манипулирует необработанными паролями)
или что-то вроде ...
@stock.current_price
, где @stock
- это объект ActiveRecord::Base
, но .current_price
вычисляется или извлекается из API при создании экземпляра объекта @stock
, поскольку нет смысла сохранять и извлекать из БД постоянно изменяющееся значение такие как цена акции в любой данный момент времени.