2

我想通過ActiveRecord獲取下一個/上一個記錄。根據'updated_at'列的順序檢索記錄在Ruby on Rails上的ActiveRecord中獲取下一個/上一個記錄

模型的名稱是'Youtube'。而作爲以下控制檯,此代碼無法獲得正確的記錄,我猜我的代碼的想法似乎不好,因爲updated_at並不總是唯一的所以一些記錄可能有相同的時間戳

如何以正確的方式獲取下一個/上一個記錄?

控制檯如下所述。

[57] pry(main)> Youtube.find(1000) 
    Youtube Load (0.5ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 1000]] 
=> #<Youtube id: 1000, author_id: 2, category_label: nil, generated_by: 1, title: "Is Kenya Mall Shooting Over? Were Americans Among A...", video_id: "4T1szQIQcNI", created_at: "2013-09-30 18:31:21", updated_at: "2013-10-27 02:19:56", subtitles: nil> 
[58] pry(main)> Youtube.find(1000).next 
    Youtube Load (0.6ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 1000]] 
Sun, 27 Oct 2013 02:19:56 UTC +00:00 
    Youtube Load (256.6ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at > '2013-10-27 02:19:56.593969') ORDER BY updated_at DESC LIMIT 1 
=> #<Youtube id: 67003, author_id: 75, category_label: nil, generated_by: 1, title: "Jewelry Photography : Lenses for Jewelry Photograph...", video_id: "NqA7OZL4tzw", created_at: "2013-10-09 17:18:53", updated_at: "2013-10-28 02:17:33", subtitles: nil> 
[59] pry(main)> Youtube.find(1000).previous 
    Youtube Load (0.6ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 1000]] 
Sun, 27 Oct 2013 02:19:56 UTC +00:00 
    Youtube Load (56.3ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at < '2013-10-27 02:19:56.593969') ORDER BY updated_at DESC LIMIT 1 
=> #<Youtube id: 999, author_id: 8, category_label: nil, generated_by: 1, title: "[email protected]: Richard Moore, Ned Boulting, and Da...", video_id: "4SCzfuJAyJw", created_at: "2013-09-30 18:31:21", updated_at: "2013-10-27 02:19:55", subtitles: nil> 

Youtube有以下的default_scope。雖然這可能會根據某些情況而改變,但我希望這些代碼能夠保持現有的行爲。

default_scope order('updated_at DESC') 

我的Youtube模型的試用代碼如下。

scope :next, lambda{|updated_at| where("updated_at > ?", 
    updated_at).order("updated_at DESC")} 
    scope :previous, lambda {|updated_at| where("updated_at < ?", 
    updated_at).order("updated_at DESC")} 

...

def next 
    self.class.next(updated_at).first 
    end 

    def previous     
    self.class.previous(updated_at).first 
    end 
+0

在這裏看到:http://stackoverflow.com/questions/7394088/rails-get-next-previous-record –

+0

達米安,我檢查http://stackoverflow.com/questions/7394088/rails-get-next-previous-record,但它不是這種情況下正確的解決方案,如上所述。 – gipcompany

+0

可能重複的[Rails:「下一篇文章」和「以前的帖子」鏈接在我的節目視圖,如何?](http://stackoverflow.com/questions/1275963/rails-next-post-and-previous-post -links-in-my-show-view-how-to) –

回答

4

我曾嘗試和錯誤,並發現下面是一解決方案。

代碼在這裏。

def next 
    self.class.unscoped.where("updated_at <= ? AND id != ?", updated_at, id).order("updated_at DESC").first 
    end 

    def previous 
    self.class.unscoped.where("updated_at >= ? AND id != ?", updated_at, id).order("updated_at ASC").first 
    end 

test is here。

[210] pry(main)> Youtube.find(100) 
    Youtube Load (0.8ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 100]] 
=> #<Youtube id: 100, author_id: 5, category_label: nil, generated_by: 1, title: "Woman's Profane Dunkin Donuts Rant Goes Viral", video_id: "-aqN7KdWgQE", created_at: "2013-09-30 18:19:42", updated_at: "2013-10-27 00:47:37", subtitles: nil> 
[211] pry(main)> Youtube.find(100).next 
    Youtube Load (0.7ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 100]] 
    Youtube Load (95.9ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at <= '2013-10-27 00:47:37.241076' AND id != 100) ORDER BY updated_at DESC LIMIT 1 
=> #<Youtube id: 99, author_id: 6, category_label: nil, generated_by: 1, title: "Editing physical locations in Google Maps", video_id: "-amPC4fcY0U", created_at: "2013-09-30 18:19:42", updated_at: "2013-10-27 00:47:36", subtitles: nil> 
[212] pry(main)> Youtube.find(100).next.previous 
    Youtube Load (0.7ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 100]] 
    Youtube Load (68.8ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at <= '2013-10-27 00:47:37.241076' AND id != 100) ORDER BY updated_at DESC LIMIT 1 
    Youtube Load (79.5ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at >= '2013-10-27 00:47:36.162671' AND id != 99) ORDER BY updated_at ASC LIMIT 1 
=> #<Youtube id: 100, author_id: 5, category_label: nil, generated_by: 1, title: "Woman's Profane Dunkin Donuts Rant Goes Viral", video_id: "-aqN7KdWgQE", created_at: "2013-09-30 18:19:42", updated_at: "2013-10-27 00:47:37", subtitles: nil> 
[213] pry(main)> Youtube.find(100) === Youtube.find(100).next.previous 
    Youtube Load (0.8ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 100]] 
    Youtube Load (4.8ms) SELECT "youtubes".* FROM "youtubes" WHERE "youtubes"."id" = $1 ORDER BY updated_at DESC LIMIT 1 [["id", 100]] 
    Youtube Load (99.7ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at <= '2013-10-27 00:47:37.241076' AND id != 100) ORDER BY updated_at DESC LIMIT 1 
    Youtube Load (79.6ms) SELECT "youtubes".* FROM "youtubes" WHERE (updated_at >= '2013-10-27 00:47:36.162671' AND id != 99) ORDER BY updated_at ASC LIMIT 1 
=> true 
0

我會做這樣的(可能是更好的方式)......

scope :in_order, lambda{ order("updated_at DESC, id ASC") } 

def next 
    self.class.in_order.where("updated_at >= ? AND id != ?", updated_at, id).first 
end 

def previous 
    self.class.in_order.where("updated_at <= ? AND id != ?", updated_at, id).first 
end 
+0

謝謝!此代碼顯示Youtube.find(x)不等於Youtube.find(x).next.previous。但是這段代碼給我一個小技巧,我已經解決了並且自我回答了上面的問題。 – gipcompany

2

我寫的自動生成這樣的質疑寶石,order_query

class YouTube < ActiveRecord::Base 
    include OrderQuery 
    order_query :order_display, [ 
    [:updated_at, :desc], 
    [:id, :desc] 
    ] 
end 

video = YouTube.find(42) 
pos = video.order_display 
video.next 
video.after 
video.position 
video.prev 
video.before 
相關問題