(实际数字大100倍,但更容易解释如下)
我们有5家餐厅的100条评论记录。有些餐厅有3或4条评论,其中一些有20-30条评论。
目前我有一份简单的报告,可以安排从最新到最旧的报告:
@reviews = Review.joins(:store).
where('reviews.published= ?',true).
order("reviews.created_at DESC")
对于我的一个报告视图,我需要以循环顺序显示评论,以确保每个餐厅在列表顶部获得相同的覆盖率。
most recent for restaurant #A
most recent for restaurant #B
...
most recent for restaurant #E
然后重复下一个最近的#A,#B,... #E
等
理想情况下,循环法的顺序是哪个餐厅的评论最多。
在代码中缓慢的方式并不难,但我想知道是否有更快/更好的activerecord方法?
===
有没有办法(a)按餐厅排序,(b)创建一个临时的“柜台”栏,每个餐厅的每个条目从1到N,(c)在该柜台栏重新排序?那样做。
例如,在(a)和(b)之后,记录集将是
A , <some review>, 1
A , <some review>, 2
...
A , <some review>, 23
B , <some review>, 1
B , <some review>, 2
...
B , <some review>, 11
C , <some review>, 1
C , <some review>, 2
...
C , <some review>, 9
如果我可以在柜台上对该记录集进行排序,它将循环A,B,C等
答案 0 :(得分:1)
您可以在数据库last_displayed
中添加一列,并在每次展示餐馆时更新该列,并始终对.order('last_displayed')
进行排序。
我还认为您可以在显示后使用updated_at
列,touch
记录,并按该列排序 - 这样您就不需要更新数据库结构了
答案 1 :(得分:1)
我最近实现了类似的东西。在我的模型中,我创建了这个方法:
def self.order_jobs
ordered_jobs = []
jobs = Job.all.to_a
jobs.each do |j|
ordered_jobs.push jobs.delete_at(jobs.find_index {|j| j.company == 'Redhat'}) unless (jobs.find_index {|j| j.company == 'Redhat'}).nil?
ordered_jobs.push jobs.delete_at(jobs.find_index {|j| j.company == 'Zapier'}) unless (jobs.find_index {|j| j.company == 'Zapier'}).nil?
ordered_jobs.push jobs.delete_at(jobs.find_index {|j| j.company == 'Mozilla'}) unless (jobs.find_index {|j| j.company == 'Mozilla'}).nil?
ordered_jobs.push jobs.delete_at(jobs.find_index {|j| j.company == 'Ubuntu'}) unless (jobs.find_index {|j| j.company == 'Ubuntu'}).nil?
ordered_jobs.push jobs.delete_at(jobs.find_index {|j| j.company == 'Digital Ocean'}) unless (jobs.find_index {|j| j.company == 'Digital Ocean'}).nil?
end
ordered_jobs
end
然后在控制器中我简单地调用Job.order_jobs:
def index
@jobs = Job.order_jobs
end
在order_jobs方法中,我首先创建两个数组。一个是DB(作业)中的现有作业,另一个是(ordered_jobs),我将以循环顺序移动作业。神奇的是ordered_jobs.push jobs.delete_at(jobs.find_index {|j| j.company == 'Redhat'})
;这表示找到Redhat公司的工作,并将其从jobs数组移动到ordered_jobs数组。一旦job数组不再具有符合给定条件的元素,unless
和.nil?
愚蠢允许您移过该代码。