Alex Rivera | Logout

Rails: "Next post" and "Previous post" links in my show view, how to?

Asked 2009-08-14T03:54:28.750
26

I'm new in Rails... smile

In my blog aplication I want to have a "Previous post" link and a "Next post" link in the bottom of my show view.

How do I do this?

Thanks!

Edit
Report

1 Answer

6

My method will allow you to automatically use model scopes. For example, you may only want to display posts that are "published."

In your model:

def self.next(post)
  where('id < ?', post.id).last
end

def self.previous(post)
  where('id > ?', post.id).first
end

In your view

<%= link_to 'Previous', @posts.previous(@post) %>
<%= link_to 'Next', @posts.next(@post) %>

In your controller

@photos = Photo.published.order('created_at')

Associated RSpec tests:

describe '.next' do
  it 'returns the next post in collection' do
    fourth_post = create(:post)
    third_post = create(:post)
    second_post = create(:post)
    first_post = create(:post)

    expect(Post.next(second_post)).to eq third_post
  end

  it 'returns the next post in a scoped collection' do
    third_post = create(:post)
    decoy_post = create(:post, :published)
    second_post = create(:post)
    first_post = create(:post)

    expect(Post.unpublished.next(second_post)).to eq third_post
  end
end

describe '.previous' do
  it 'returns the previous post in collection' do
    fourth_post = create(:post)
    third_post = create(:post)
    second_post = create(:post)
    first_post = create(:post)

    expect(Post.previous(third_post)).to eq second_post
  end

  it 'returns the previous post in a scoped collection' do
    third_post = create(:post)
    second_post = create(:post)
    decoy_post = create(:post, :published)
    first_post = create(:post)

    expect(Post.unpublished.previous(second_post)).to eq first_post
  end
end

Note: there will be small issues when you reach the first/last post in a collection. I recommend a view helper to conditionally show the previous or next button only if it exists.

answered 2013-06-29T22:23:00.653

Your Answer