2011-09-12 45 views
40

我的應用程序具有屬於用戶的照片。Rails:獲取下一個/上一個記錄

在照片中#show view我想顯示「來自此用戶的更多內容」,並顯示該用戶的下一張和上一張照片。我會很好,這些是在id訂單的下一張/上一張照片或created_at訂單的下一張/上一張照片。

你將如何爲一張下一張/上一張照片或多張下一張/上一張照片編寫這種查詢?

+0

這顆寶石完全適合我。 http://stackoverflow.com/a/25712023/683157 – kuboon

回答

80

試試這個:

​​

現在,您可以:

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

不知道這是Rails的3.2+的改變,但不是:

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

爲以前。你所要做的

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

看來,「ORDER BY」是錯誤的,所以首先給你的數據庫的第一條記錄,因爲如果你有比目前更低的3項,[1,3,4 ],那麼「第一個」是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

我已經創建了具有相同行爲的gem,但另一種方法是:https://github.com/dmitry/proximal_records –

12

它引導我解決我的問題。我正在嘗試爲項目製作下一個/ prev,不涉及任何關聯。結束了做這樣的事情在我的模型:

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 

我發現這裏的答案沒有爲我的情況服務。想象一下,您希望根據發佈的日期獲取上一張或下一張,但某些照片會在相同的日期發佈。此版本將按照它們在頁面上呈現的順序循環顯示照片,並在集合中當前照片的前後拍攝照片。

相關問題