Rails и пагинация Kaminari с определенным приоритетом на страницу - PullRequest
0 голосов
/ 29 октября 2018

У меня сложный запрос, который я написал частично как представление базы данных MySQL и частично как логика ActiveRecord в Rails. Каждая запись имеет свой собственный приоритет от 0 до 4, где 4 является высшим приоритетом.

Я использую Kaminari для нумерации страниц, и мне интересно, есть ли способ показать наборы записей для каждой страницы с некоторыми дополнительными правилами:

  1. Показать все # 4 приоритетных строки на первой странице
  2. Возьмите номер per_page и покажите приоритет 3 по следующей формуле: 0.3 * per_page
  3. Затем сделайте то же самое с приоритетом 2
  4. Тогда, если все 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

1 Ответ

0 голосов
/ 29 октября 2018

Это звучит как более сложная логика, чем Каминари, и, вероятно, стоит сделать это самостоятельно. Kaminari, безусловно, удобен для быстрого создания пользовательского интерфейса для разбивки на страницы, но на самом деле он не приносит огромной пользы по сравнению с собственным решением. Возможно, вы сможете взломать его под свои нужды, но это, вероятно, больше головной боли, чем просто сделать это самостоятельно.

Я также немного скептически отношусь к тому, что сложный алгоритм, который вам нужен, действительно пойдет на пользу пользователям. Только вы знаете это наверняка, но вы можете рассмотреть простой столбец «оценка» или «рейтинг», а затем просто использовать Kaminari с запросом, отсортированным по счету desc.

...