2011-09-12 6 views
40

私のアプリにはユーザーに属する写真があります。Rails:次/前のレコードを取得

写真#show view "More from this user"を表示し、そのユーザーからの次の写真と前の写真を表示したいと思います。私はidの次の/前の写真、またはcreated_atの次の/前の写真であることでこれらはうまくいくでしょう。

どのように次の/前の写真、または複数の次回/前の写真のためのそのような種類のクエリを書いてくださいか?

+0

この宝石は私にとって完璧に機能しました。 http://stackoverflow.com/a/25712023/683157 – kuboon

答えて

80

これを試してみてください。今すぐ

​​

することができます:

これは代わりの、3.2以上のRailsの変化である場合
photo.next 
photo.prev 
+0

prevはこのように正しく動作しませんuser.photos.where( "id <?"、id).last、ありがとうとにかく – igrek

+3

@igrek I答えが決まった一般に、大きなデータセットを持っている場合、パフォーマンスに影響を与えるので、 'last'コールを使用しないようにします(http://stackoverflow.com/questions/4481388/why-does-mysql-higher-limit-offset-slow-the-クエリダウン)。最後の行に移動するには、 'ORDER BY id DESC'節を使用します。 –

+0

制限(1)を使うのはどうですか? –

2

あなたはどこの方法にいくつかのオプションを渡すことができます。私は最後の/最初は混ざっていて

Photo.where(:user_id => current_user.id, :created_at > current_photo.created_at).order("created_at").first 

前の写真

Photo.where(:user_id => current_user.id, :created_at < current_photo.created_at).order("created_at").last 

:次の写真について

8

わからないための:

model.where("id < ?", id).first 

前。あなたは1,3,4 [、それは間違っているので、あなたが現在より低い3つのアイテムを持っている場合ので、最初、あなたのDB内の最初のレコードを与える「ことで順序」と思われ

.where("id > ?", id).last 

をしなければなりません]、 "first"は1ですが、最後のものはあなたが探しているものです。場所の後ろに並べ替えを適用することもできますが、余分なステップがあります。

+1

マイナスとは何ですか?これは完璧ですか? – jwilcox09

+0

これは私が確認できます。 – Hendrik

3
class Photo < ActiveRecord::Base 
    belongs_to :user 
    scope :next, lambda {|id| where("id > ?",id).order("id ASC") } # this is the default ordering for AR 
    scope :previous, lambda {|id| where("id < ?",id).order("id DESC") } 

    def next 
    user.photos.next(self.id).first 
    end 

    def previous 
    user.photos.previous(self.id).first 
    end 
end 

その後、次のことができます。

photo.previous 
photo.next 
1

あなたはNexterをチェックすることをお勧めします。 モデルにハードコードされたものに頼るのではなく、動的に作成されたスコープで動作します。

+0

私は同じような振る舞いで宝石を作りましたが、他のアプローチ:https://github.com/dmitry/proximal_records –

12

私の問題の解決策にもつながります。私はアイテムのために次の/前のものを作りようとしていましたが、関連はありませんでした。

def next 
    Item.where("id > ?", id).order("id ASC").first || Item.first 
    end 

    def previous 
    Item.where("id < ?", id).order("id DESC").first || Item.last 
    end 

、それが最初のものと他の方法で回避に行く最後の項目から、周りのループこの方法:私のモデルでは、このようなことをやってしまいました。 私は後で@item.nextと呼んでいます。

+0

素晴らしい繰り返しです。 –

+0

ニースは、同様にサイクルを探していた! – gregblass

1
class Photo < ActiveRecord::Base 
    belongs_to :user 

    default_scope { order('published_at DESC, id DESC') } 

    def next 
    current = nil 
    user.photos.where('published_at >= ?', published_at).each do |p| 
     if p.id == id then break else current = p end 
    end 
    return current 
    end 

    def previous 
    current = nil 
    user.photos.where('published_at <= ?', published_at).reverse.each do |p| 
     if p.id == id then break else current = p end 
    end 
    return current 
    end 
end 

ここでの回答は私の場合には役に立たないことがわかりました。あなたが出版された日付に基づいて前または次を望んでいると想像してください、しかし、いくつかの写真は同じ日付に公開されています。このバージョンでは、ページ上でレンダリングされた順番に写真をループし、コレクション内の現在のものの前後にあるものを取ります。

関連する問題