Col*_*eal 4 ruby activerecord ruby-on-rails
我有一个问题按当前日期排序数组.
我的数据库有一个名为的字段 day
day
有周如的日子:Monday
,Tuesday
,等.
我正在尝试按索引视图页面排序current day
.
我想在我的控制器中做这样的事情,
@happies = Happy.where(id: @search.results.map(&:id))
.page(params[:page])
.where(:day => Date.today.strftime('%A').capitalize.to_s)
Run Code Online (Sandbox Code Playgroud)
但而不是返回only
与天人们高兴Monday
我想order
通过day
这里day
等于current day
.
在我看来,我也考虑过这样做
喜欢的东西
<% @happies.sort_by(:day => Date.today.strftime('%A').capitalize.to_s).each do |happy| %>
上面的方法不起作用,但是我试图实现我想达到的目标.有关如何实现这一点的任何想法?
也许有一个activeview助手?
如果你没有分页,你可以用普通红宝石对结果进行排序,如下所示:
day_order = %w(Tuesday Wednesday Thursday Friday Saturday Sunday Monday)
@happies = @happies.sort_by{|happy| day_order.index(happy.day)}
Run Code Online (Sandbox Code Playgroud)
sort_by
获取一个块,返回值以进行排序.
但是,您似乎正在使用分页will_paginate
.这样很好,但它会让事情变得更复杂.
分页必然通过限制和偏移在数据库中发生(以避免将表的全部内容返回到Rails进程).因此,您希望排序也发生在数据库中.如果你要在ruby中进行排序(如上所述),你将在分页后进行排序,这意味着第一页会给你基本上随机的结果,然后你会对它们进行排序.可能不是你想要的.
长话短说,您可能想要使用order
而不是sort_by
,我将不得不深入研究SQL:
@happies = Happy.where(id: @search.results.map(&:id))
.page(params[:page])
.order("CASE day WHEN 'Tuesday' THEN 0 " \
"WHEN 'Wednesday' THEN 1 " \
"WHEN 'Thursday' THEN 2 " \
"WHEN 'Friday' THEN 3 " \
"WHEN 'Saturday' THEN 4 " \
"WHEN 'Sunday' THEN 5 " \
"WHEN 'Monday' THEN 6 END")
Run Code Online (Sandbox Code Playgroud)
如果你想避免使用SQL,也许可以使用Arel,我不确定.
编辑
我现在看到你想从当天开始,即不像我那样硬编码为星期二.要修复我的SQL版本 - 并从@ Snarf的答案中借一点 - 你可以这样做:
days = %w(Monday Tuesday Wednesday Thursday Friday Saturday Sunday)
days.rotate!(days.index(Time.zone.now.strftime("%A")))
case_pieces = days.each_with_index.map do |day, i|
"WHEN '#{day}' THEN #{i}"
end
@happies = Happy.where(id: @search.results.map(&:id))
.page(params[:page])
.order("CASE day #{case_pieces.join(' ')} END")
Run Code Online (Sandbox Code Playgroud)
另一种想法
如果我自己编写应用程序,我很想把这一天存储为0到6之间的整数,而不是字符串.然后你可以使用modulo运算符,如下所示:
days = %w(Monday Tuesday Wednesday Thursday Friday Saturday Sunday)
day_offset = days.index(Time.zone.now.strftime("%A"))
@happies = Happy.where(id: @search.results.map(&:id))
.page(params[:page])
.order("(day - #{day_offset} + 7) % 7")
Run Code Online (Sandbox Code Playgroud)