假设您有一个具有投票属性的项目模型。这可能是一些示例数据:
Item, Votes
-----------
Red 4
Blue 5
Black 5
Green 4
Cyan 5
Yellow 4
Orange 4
我想要一个首先通过投票对其进行排序的范围:
Item, Votes
-----------
Orange 4
Green 4
Yellow 4
Red 4
Blue 5
Black 5
Cyan 5
然后在每个投票队列中随机化:
Item, Votes
-----------
Green 4
Red 4
Orange 4
Yellow 4
Black 5
Blue 5
Cyan 5
然后将其限制为前两个结果。
我试过这个:
scope :options, -> { order('random()').order("votes asc").limit 2 }
和此:
scope :options, -> { order("votes asc").order('random()').limit 2 }
但两者都没有按预期工作。第一个版本似乎是完全随机的,第二个版本根本不是随机的。
答案 0 :(得分:1)
根据您的具体需求,您有两种选择。如果您想要完整结果中的前两个(下面突出显示),那么您的第二个解决方案将起作用。但是,如果您想要每个组的第一行,您需要稍微修改一下您的查询(如下所示:)
完整结果的第一行:
scope :options, -> { order('votes ASC, random()').limit(2) }
将选择以下行:
Item, Votes
-----------
Green 4 *
Red 4 *
Orange 4
Yellow 4
Black 5
Blue 5
Cyan 5
每组的第一行:
scope :options, -> { select('DISTINCT ON (votes) *').order('votes ASC, random()').limit(2) }
将选择以下行:
Item, Votes
-----------
Green 4 *
Red 4
Orange 4
Yellow 4
Black 5 *
Blue 5
Cyan 5
答案 1 :(得分:0)
就分拣而言,有一个很棒的宝石叫做“Ransack”' (https://github.com/activerecord-hackery/ransack)允许动态排序数据集。我担心自己无法提供其他问题,但希望这有助于排序!
答案 2 :(得分:0)
在项目模型中我制作了这个方法:
def rand_value
self.votes + Random.rand
end
然后在控制器中我使用此查询:
@items = @experiment.items.sort_by { |item| [item.rand_value] }
这似乎像我想要的那样工作。列表中的第一项始终是投票率最低的项目,但在每个队列中,它们都是随机的。唯一的缺点是它不仅限于两个结果。