Вот Ruby OO head scratch для вас, вызванный этим сценарием Rails:
class Product < ActiveRecord::Base
has_many(:prices)
# define private helper methods
end
module PrintProduct
attr_accessor(:isbn)
# override methods in ActiveRecord::Base
end
class Book < Product
include PrintProduct
end
Product
является базовым классом всех продуктов. Книги хранятся в таблице products
через STI. Модуль PrintProduct
обеспечивает некоторое общее поведение и состояние для потомков Product
. Book
используется внутри fields_for
блоков в представлениях. Это работает для меня, но я обнаружил странное поведение:
- После отправки формы внутри моего контроллера, если я вызываю метод для книги, определенной в
PrintProduct
, и этот метод вызывает вспомогательный метод, определенный в Product
, который, в свою очередь, вызывает определенный метод prices
на has_many
я получу ошибку, сообщающую, что Book#prices
не найден.
Почему это? Книга является прямым потомком Продукта!
Более интересно следующее ..
Когда я разработал эту иерархию, PrintProduct
начал становиться более абстрактным ActiveRecord::Base
, поэтому я подумал, что разумно переопределить все как таковое:
class Product < ActiveRecord::Base
end
class PrintProduct < Product
end
class Book < PrintProduct
end
Все определения методов и т. Д. Одинаковы. В этом случае, однако, моя веб-форма не будет загружаться, потому что атрибуты, определенные attr_accessor
(которые являются «виртуальными атрибутами», на которые ссылается форма, но которые не сохраняются в БД), не найдены. Я получу сообщение о том, что нет метода Book#isbn
. Это почему?? Я не вижу причины, по которой атрибуты attr_accessor
не найдены внутри блока fields_for
моей формы, когда PrintProduct
является классом, но они обнаруживаются, когда PrintProduct
является Module
.
Любое понимание будет оценено. Я до смерти хочу знать, почему эти ошибки происходят!