Rails 2.3.4: Как отфильтровать модели с одинаковыми таблицами на основе их собственного типа? - PullRequest
0 голосов
/ 29 июня 2011

Рассмотрим следующий пример кода:

def Product < ActiveRecord::Base
end

def Book < Product
end

(Я перестал искать имя для такого рода отношений. Я думал, что Book - это «дочерняя модель», а Product - «родительский», но этоНапример, объект модели Comment, связанный с другим объектом модели Comment, - это то, что было бы отношением «ребенок-родитель». Если у вас есть лучший способ описать отношения моделей в моем коде выше, добро пожаловатьзаписать это здесь. В любом случае, это не совсем то, почему я здесь.)

Конечно, с помощью приведенного выше кода модель Book будет использовать ту же таблицу базы данных, что и Product, «продукты».Тип модели будет сохранен в виде строки в столбце «тип» таблицы.Таким образом, вызов Product.create вставит строку в таблицу со значением типа, установленным в «Product», а использование с Book.create сделает то же самое, но со значением «Book».

Что меня озадачиваетоднако вызов Book.last вернет последнюю строку с типом «Книга», как я и ожидал, но Product.last вернет последнюю строку независимо от типа, включая «Продукт» и «Книга», даже еслиЯ хочу получить только последний «Продукт».

Я попытался определить значение default_scope в Product, которое переопределяю в своей Книге, но это вызывает больше проблем, чем решает, и испортил мои именованные области в Product, которыеУнаследовано от Book.

Есть ли способ заставить Product.last возвращать последний объект типа "Product" и избегать любых объектов типа "Book"?

Заранее спасибо за ваши ответы.

Ответы [ 2 ]

0 голосов
/ 29 июня 2011

Основное недопонимание здесь, по-видимому, связано с понятием «отношения» или «ассоциации» (например, «has_one», «own_to» и т. Д.) И объектно-ориентированной концепцией наследования.

Читайте об этом: http://rubylearning.com/satishtalim/ruby_inheritance.html

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

Когда класс наследует от другого класса (в вашем примере Book наследует от Product), «дочерний» класс получает все функциональные возможности «родительского» класса, а также любые новые функциональные возможности, которые он добавляет к этому.

Из-за этого все Книги являются Продуктами, но не все Продукты являются Книгами .

Причина, по которой Product.last возвращает последнюю строку в таблице товаров независимо от ее типа, заключается в том, что все товары (включая книги) являются товарами. Таким образом, Книга - это продукт, поэтому, если последний Продукт - это Книга, она будет возвращена.


Хорошо, поэтому самый простой способ выполнить то, что вы пытаетесь сделать здесь, это определить все типы Продуктов как подтипы Продукта и никогда не использовать Product.last.

Допустим, вы отслеживаете книги, компакт-диски и автомобили

книга класса <Продукт Класс CD <Продукт Класс Car <Товар </p>

Таким образом, когда вам нужно добавить в базу данных новейшую Книгу, CD или Автомобиль, вы делаете Book.last, CD.last или Car.last. Если вам просто нужно знать новейший продукт любого типа , вы должны сделать Product.last.

0 голосов
/ 29 июня 2011

Мне кажется довольно ясным, что Product.last должен возвращать последнюю строку, поскольку в вашей таблице все является "Product". То, что вы хотите сделать, - это поиск определенного типа «Продукт», но, как выясняется, таблица фактически не устанавливает тип для продукта, она просто оставляет его равным нулю.

Так что на самом деле это работает, я думаю:

Product.find_last_by_type(nil)

Можешь попробовать? Я проверил на другом столе, но я думаю, что это должно работать.

...