2013-09-05 3 views
3

В моем проекте ruby ​​on rails я создал несколько разных моделей. В настоящее время различными типами моделей являются статьи, быстрые подсказки, цитаты и определения. Я создал страницу, где я хотел бы отображать все эти данные в одном потоке, упорядоченном по времени создания.Извлечение множества разных моделей из базы данных в то же время

Вопрос: Что такое разумный/эффективный способ получения определенного количества элементов, выбранных среди всех типов контента, упорядоченных по дате создания.

Надеюсь иллюстративный псевдокод:

Db.load([:Tip, :Quote, :Article, :Definition]).order_by(:created_at).limit(10) 

Лучшее решение, которое я придумал сам до сих пор, чтобы загрузить 10 пунктов каждой категории, сортировать их и забрать последние 10 из отсортированного списка. : P

+0

Было бы полезно, если бы вы могли предоставить схему для таблиц. –

+0

Вы можете создать VIEW в SQL (http://stackoverflow.com/questions/13656864/sql-create-view-from-multiple-tables), а затем запросить это представление, чтобы получить все последние записи. – MrYoshiji

+0

MrYoshiji, ваш ответ зависит от того, существуют ли общие идентификаторы или что-то, к чему можно подключиться, однако эти таблицы не имеют ничего общего. Поэтому я не хочу ничего комбинировать в составные строки, я просто хочу получить данные из нескольких таблиц сразу, отсортированные по дате создания, _efficiently_. – Daniel

ответ

0

Так способ сделать то, что я хочу сделать суперкласс, скажет Post, и есть все остальные типы контента наследуют от этой модели. Это создаст схему однонаправленного наследования, в которой все атрибуты подкласса хранятся в таблице «posts» вместе с атрибутом «type», который упрощает дифференциацию между типами контента. Я все равно должен использовать все типы контента, но также получить модель сообщений, в которой я могу одновременно запрашивать и сортировать все типы контента.

More information about the technique can be found here

0

Просто соедините их.

(Tip.all + Quote.all + Article.all + Definition.all).order_by(:created_at).limit(10) 

Или

tips = Tips.all.limit(10) 
quotes = Quotes.all.limit(10) 
(tips + quotes).order_by(:created_at).limit(10) 

Получить идею?

Possibly useful similar question

+0

Я был очень взволнован этим ответом, поскольку это казалось изящным решением, но я боюсь, что это не сработает. Проблема в том, что конкатенация массивов не создает новое отношение ActiveRecord, а обычный Ruby Array, который не имеет методов order_by или limit. Ссылка, которую вы предоставили, была полезной, но ответ там загружает объекты в массив, а затем сортирует их (в отличие от того, что он отсортирован непосредственно в поиске из базы данных). По сути, это дает то же самое решение, что и я, описанный в нижней части моего вопроса ... но, возможно, нет лучшего решения? – Daniel

+0

Да. Это плохо. Я не проверял. Второй ответ может быть отсортирован вручную, а затем ограничен. – screenmutt

0
[Tip, Quote, Article, Definition].map{|model_name| model_name.order(:created_at).first(10)} 
+0

Таким образом, этот код essentialy создает массив массивов, где каждый субмассив содержит 10 элементов заданного типа, отсортированных по дате создания. Это не то, о чем я просил.Мне нужен единственный массив объектов всех видов, которые сортируются по времени создания и, если возможно, без загрузки более 10 объектов. Этот ответ загружает 40 объектов из базы данных, когда в каждой категории достаточно объектов. – Daniel

+0

О, я понял это неправильно. Почему не sql-запрос 'select column_name из советов union select column_name из кавычек union select column_name из статей union select column_name из определений order by created_at;' Затем выполните соединение = ActiveRecord :: Base.connection; ActiveRecord :: Base.connection.execute (запрос). – deepthi

+0

Это хорошая идея, однако разные таблицы не имеют одинакового количества полей, что требуется для объединения. Другой, возможно, сравнительно небольшой, оговорка заключается в том, что соединение возвращает хеши вместо моделей. – Daniel

Смежные вопросы