gip*_*any 2 ruby activerecord ruby-on-rails ruby-on-rails-3.2 rails-activerecord
我想通过ActiveRecord获取下一个/上一个记录.应根据'updated_at'列的顺序检索记录.
模型的名称是'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: "Authors@Google: 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>
Run Code Online (Sandbox Code Playgroud)
Youtube具有以下default_scope.虽然这可能会根据某些情况而改变,但我希望这些代码能够保持现有的行为.
default_scope order('updated_at DESC')
Run Code Online (Sandbox Code Playgroud)
我的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")}
Run Code Online (Sandbox Code Playgroud)
...
def next
self.class.next(updated_at).first
end
def previous
self.class.previous(updated_at).first
end
Run Code Online (Sandbox Code Playgroud)
我确实尝试和错误,发现下面是解决方案之一.
代码在这里.
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
Run Code Online (Sandbox Code Playgroud)
测试就在这里.
[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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4308 次 |
| 最近记录: |