Rails:我的节目视图中的"下一篇文章"和"上一篇文章"链接,如何?

pol*_*oco 25 ruby-on-rails

我是Rails的新手......微笑

在我的博客应用程序中,我希望在我的节目视图的底部有一个"上一篇文章"链接和一个"下一篇文章"链接.

我该怎么做呢?

谢谢!

rya*_*anb 43

如果每个标题都是唯一的并且您需要按字母顺序排列,请在Post模型中尝试使用.

def previous_post
  self.class.first(:conditions => ["title < ?", title], :order => "title desc")
end

def next_post
  self.class.first(:conditions => ["title > ?", title], :order => "title asc")
end
Run Code Online (Sandbox Code Playgroud)

然后,您可以链接到视图中的那些.

<%= link_to("Previous Post", @post.previous_post) if @post.previous_post %>
<%= link_to("Next Post", @post.next_post) if @post.next_post %>
Run Code Online (Sandbox Code Playgroud)

未经测试,但它应该让你接近.如果需要不同的排序顺序,可以更改title为任何唯一属性(created_at,id等).


小智 13

我使用下面的模型方法来避免id + 1不存在但id + 2的问题.

def previous
  Post.where(["id < ?", id]).last
end

def next
  Post.where(["id > ?", id]).first
end
Run Code Online (Sandbox Code Playgroud)

在我的视图代码中,我只是这样做:

  - if @post.previous
    = link_to "< Previous", @post.previous
  - if @post.next
    = link_to "Next >", @post.next
Run Code Online (Sandbox Code Playgroud)


Nea*_*eal 5

我的方法将允许您自动使用模型范围。例如,您可能只想显示“已发布”的帖子。

在您的模型中:

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

def self.previous(post)
  where('id > ?', post.id).first
end
Run Code Online (Sandbox Code Playgroud)

在你看来

<%= link_to 'Previous', @posts.previous(@post) %>
<%= link_to 'Next', @posts.next(@post) %>
Run Code Online (Sandbox Code Playgroud)

在您的控制器中

@photos = Photo.published.order('created_at')
Run Code Online (Sandbox Code Playgroud)

相关的 RSpec 测试:

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
Run Code Online (Sandbox Code Playgroud)

注意:当您到达集合中的第一个/最后一个帖子时,会出现一些小问题。我推荐一个视图助手,只有当它存在时才有条件地显示上一个或下一个按钮。