Rails和Kaminari分页,每页优先

时间:2018-10-29 15:55:54

标签: mysql ruby-on-rails kaminari

我有一个复杂的查询,部分是作为MySQL数据库视图编写的,一部分是作为Rails中的ActiveRecord逻辑编写的。每个记录都有自己的优先级,从0-4,其中4是最高优先级。

我正在使用Kaminari进行分页,我想知道是否有一种方法可以显示带有某些附加规则的每页记录集:

  1. 在首页上显示所有#4优先级行
  2. 获取每页编号,并使用以下公式显示优先级3:每页0.3 *
  3. 然后以优先级2进行同样的操作
  4. 然后,如果所有3个步骤都不产生per_page的100%,则显示其余的优先级为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 :(得分:2)

这听起来比Kaminari所构建的逻辑更为复杂,可能值得您自己去做。 Kaminari对于敲除快速分页UI确实很方便,但与推出自己的解决方案相比,它确实没有增加太多的价值。您也许可以根据自己的需要进行破解,但这可能比您自己动手做还要麻烦。

我也有些怀疑,您想要的复杂算法是否真的会使用户受益。只有您肯定知道这一点,但是您可能需要考虑一个简单的“得分”或“排名”列,然后将Kaminari与按分数desc排序的查询一起使用。