rails 3 + active record:有一种巧妙的方式来“循环”记录的顺序

时间:2011-07-02 08:04:17

标签: ruby-on-rails activerecord

(实际数字大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等

2 个答案:

答案 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?愚蠢允许您移过该代码。