2011-09-12 35 views
40

Ứng dụng của tôi có Ảnh thuộc về Người dùng.Đường ray: Nhận hồ sơ tiếp theo/trước đó

Trong chế độ xem # hiển thị ảnh, tôi muốn hiển thị "Thêm từ người dùng này" và hiển thị ảnh tiếp theo và trước đó từ người dùng đó. Tôi sẽ ổn với những ảnh tiếp theo/trước đó trong đơn đặt hàng id hoặc ảnh tiếp theo/trước đó theo thứ tự created_at.

Bạn sẽ viết loại truy vấn đó cho một ảnh tiếp theo/trước đó hoặc cho nhiều ảnh tiếp theo/trước đó như thế nào?

+0

Đá quý này hoàn toàn phù hợp với tôi. http://stackoverflow.com/a/25712023/683157 – kuboon

Trả lời

80

Hãy thử điều này:

class User 
    has_many :photos 
end 


class Photo 
    belongs_to :user 

    def next 
    user.photos.where("id > ?", id).first 
    end 

    def prev 
    user.photos.where("id < ?", id).last 
    end 

end 

Bây giờ bạn có thể:

photo.next 
photo.prev 
+0

trước không hoạt động bình thường theo cách này, phải là user.photos.where ("id igrek

+3

@igrek I đã sửa câu trả lời. Nói chung, tôi tránh sử dụng lệnh 'last' vì nó có tác động hiệu suất nếu bạn có một tập dữ liệu lớn (http://stackoverflow.com/questions/4481388/why-does-mysql-higher-limit-offset-slow-the- truy vấn xuống). Tôi sử dụng mệnh đề 'ORDER BY id DESC' để đến các hàng cuối cùng. –

+0

cách sử dụng giới hạn (1)? –

2

Bạn có thể vượt qua một số tùy chọn vào các phương pháp đó:

Đối với các ảnh tiếp theo:

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

Ảnh trước

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

tôi có thể có lẫn lộn là người đầu tiên/cuối cùng.

8

Không chắc nếu điều này là một sự thay đổi trong Rails 3.2+, nhưng thay vì:

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

cho Trước. Bạn phải làm

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

Có vẻ như "thứ tự" là sai, vì vậy trước tiên hãy cung cấp cho bạn bản ghi đầu tiên trong DB, vì nếu bạn có 3 mục thấp hơn hiện tại, [1,3,4 ], sau đó "đầu tiên" là 1, nhưng đó là lần đầu tiên bạn tìm kiếm. Bạn cũng có thể áp dụng một loại để sau khi ở đâu, nhưng đó là một bước bổ sung.

+1

Whats có dấu trừ. Điều này hoạt động hoàn hảo? – jwilcox09

+0

Tôi có thể xác nhận tác phẩm này. – 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 

Sau đó, bạn có thể:

photo.previous 
photo.next 
1

Bạn có thể muốn kiểm tra Nexter. Nó hoạt động trên bất kỳ phạm vi được tạo động nào thay vì dựa vào một mã được mã hóa cứng trong mô hình của bạn.

+0

Tôi đã tạo đá quý với cùng một hành vi, nhưng cách tiếp cận khác: https://github.com/dmitry/proximal_records –

12

Nó cũng dẫn tôi đến giải pháp cho vấn đề của tôi. Tôi đã cố gắng để thực hiện một kế tiếp/prev cho một mục, không có hiệp hội liên quan. kết thúc bằng việc làm điều gì đó tương tự như vậy trong mô hình của tôi:

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 

Cách này vòng quanh, từ mục cuối cùng đến mục đầu tiên và ngược lại. Tôi chỉ gọi @item.next trong quan điểm của tôi sau đó.

+0

Tuyệt vời cho chu trình lặp lại. –

+0

Đẹp, cũng đang tìm kiếm một chu kỳ! – 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 

Tôi nhận thấy rằng các câu trả lời đã có ở đây không phân phát trường hợp của tôi. Hãy tưởng tượng rằng bạn muốn có trước hoặc sau dựa trên ngày xuất bản, nhưng một số hình ảnh được xuất bản vào cùng một ngày. Phiên bản này sẽ lặp qua các bức ảnh theo thứ tự chúng được hiển thị trên trang và lấy các ảnh trước và sau ảnh hiện tại trong bộ sưu tập.

Các vấn đề liên quan