У меня сложный запрос, который я написал частично как представление базы данных MySQL и частично как логика ActiveRecord в Rails. Каждая запись имеет свой собственный приоритет от 0 до 4, где 4 является высшим приоритетом.
Я использую Kaminari для нумерации страниц, и мне интересно, есть ли способ показать наборы записей для каждой страницы с некоторыми дополнительными правилами:
- Показать все # 4 приоритетных строки на первой странице
- Возьмите номер per_page и покажите приоритет 3 по следующей формуле: 0.3 * per_page
- Затем сделайте то же самое с приоритетом 2
- Тогда, если все 3 шага не дали результата, 100% per_page показывают остаток с приоритетом 0 и 1
Как мне достичь результата с помощью Rails. Или лучше реализовать это непосредственно в SQL?
Вот пример моего представления в БД:
select *
from (
select
s.id as source_id,
'Spree::Store' as source_type,
(case when (s.created_at >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY AND s.created_at < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY)
then
'new'
else
'old'
end) as sub_type,
1 as priority,
s.created_at as created_at,
s.updated_at as updated_at,
null as owner_id
from spree_stores as s
where s.image_id is not NULL and s.is_hidden = false
union
select
e.id as source_id,
'Event' as source_type,
(case
when (e.status = 1 and e.is_featured is false)
then
'live'
when (e.is_featured = true)
then
'featured'
else
case when (e.created_at >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY AND e.created_at < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY)
then
'new'
else
'old'
end
end) as sub_type,
(case
when (e.status = 1 or e.is_featured is true)
then
3
else
1
end) as priority,
e.created_at as created_at,
e.updated_at as updated_at,
null as owner_id
from events as e
where e.status >= 1 and e.expires_at >= curdate()
union
select
o.id as source_id,
'Spree::Order' as source_type,
(case when (o.created_at >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY AND o.created_at < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY)
then
'new'
else
'old'
end) as sub_type,
1 as priority,
o.created_at as created_at,
o.updated_at as updated_at,
o.user_id as owner_id
from spree_orders as o
where o.user_id is not NULL and o.share is true and o.state = 'complete' and o.completed_at is not NULL
union
select
p.id as source_id,
'Spree::Product' as source_type,
(case when (p.created_at >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY AND p.created_at < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY)
then
'new'
else
'old'
end) as sub_type,
1 as priority,
p.created_at as created_at,
p.updated_at as updated_at,
null as owner_id
from spree_products as p
join spree_variants as sv on (sv.product_id = p.id and sv.is_master = true)
join spree_assets as sa on (sa.viewable_id = sv.id and sa.viewable_type = 'Spree::Variant')
where p.deleted_at is NULL
group by p.id
) a
order by priority desc, created_at desc;
Вот результат, который я получаю (только несколько строк, а не все 200 результатов):
![mysql view result](https://i.stack.imgur.com/DmoXU.png)