Rails:我的显示视图中的“下一篇文章”和“上一篇文章”链接,如何?

     2023-02-26     150

关键词:

【中文标题】Rails:我的显示视图中的“下一篇文章”和“上一篇文章”链接,如何?【英文标题】:Rails: "Next post" and "Previous post" links in my show view, how to? 【发布时间】:2009-08-14 03:54:28 【问题描述】:

我是 Rails 的新手...微笑

在我的博客应用程序中,我希望在我的显示视图底部有一个“上一篇文章”链接和一个“下一篇文章”链接。

我该怎么做?

谢谢!

【问题讨论】:

【参考方案1】:

如果每个标题都是唯一的并且您需要按字母顺序排列,请在您的 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

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

<%= link_to("Previous Post", @post.previous_post) if @post.previous_post %>
<%= link_to("Next Post", @post.next_post) if @post.next_post %>

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

【讨论】:

抱歉,Ryan,我一定是瞎了眼,你可以 :conditions => ["title > ? and id > ?", title, id] 来解决。除非它是一个玩具应用程序,否则在标题上添加索引在这里很重要。 语法略有不同:self.class.where("today_date &lt; ?", today_date).order(today_date: :desc).first【参考方案2】:

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

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

def next
  Post.where(["id > ?", id]).first
end

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

<% if @post.previous %>
  <%= link_to "< Previous", @post.previous %>

<% if @post.next %>
  <%= link_to "Next >", @post.next %>

【讨论】:

【参考方案3】:

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

在您的模型中:

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

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

在你看来

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

在你的控制器中

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

相关的 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

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

【讨论】:

【参考方案4】:

我就是这样做的。首先,在您的 Post 模型中添加几个 named scopes:

def previous
  Post.find_by_id(id - 1, :select => 'title, slug etc...')
end

def next
  Post.find_by_id(id + 1, :select => 'title, slug etc...')
end

请注意使用 :select 选项来限制字段,因为您可能不希望仅为了显示链接而检索完全填充的 Post 实例。

然后在我的posts_helper我有这个方法:

def sidebar_navigation_links
  next_post = @post.next
  previous_post = @post.previous
  links = ''
  if previous_post
    links << content_tag(:h3, 'Previous')
    links << content_tag(:ul, content_tag(:li,
                              content_tag(:a, previous_post.title,
                                          :href => previous_post.permalink)))
  end
  if next_post
    links << content_tag(:h3, 'Next', :class => 'next') if previous_post
    links << content_tag(:h3, 'Next') if previous_post.nil?
    links << content_tag(:ul, content_tag(:li,
                              content_tag(:a, next_post.title,
                                          :href => next_post.permalink)))
  end
  content_tag(:div, links)
end

我确信这可以重构为不那么冗长,但意图很明确。显然,您的标记要求与我的不同,因此您可能不会选择使用无序列表。

重要的是使用if 语句,因为如果您在第一篇文章中,那么它们将不是以前的文章,相反,如果您在最后一篇文章中,它们将不是下一篇文章.

最后,只需从您的视图中调用辅助方法:

<%= sidebar_navigation_links %>

【讨论】:

嗨约翰,谢谢你的回答...但是我有一个问题...如果我销毁一个帖子,我会丢失连续的 ID,我不知道下一个帖子是谁或上一篇文章,因为 Post.find_by_id(id - 1, :select => 'title, slug etc...') 另一个问题是我没有永久链接,我现在按 id 导航,但如果我替换“ :href => previous_post.permalink" by ":href => previous_post.id" href = emty :) 你能帮帮我吗?再次感谢!【参考方案5】:

试试will_paginate Gem。它提供了对帖子条目进行分页所需的所有功能。也学here

如果您想添加下一个和上一个按钮,您也可以查看 here 示例代码。

【讨论】:

will_paginate 不适合这个问题。当您显示帖子时,您处理的是单个帖子,而不是集合。【参考方案6】:

我专门为此类任务创建了 gem proximal_records,它适用于您模型中任何动态创建的范围。

https://github.com/dmitry/proximal_records

基本示例:

class Article < ActiveRecord::Base
  include ProximalRecords
end


scope = Article.title_like('proximal').order('created_at DESC, title ASC')
current_record = scope.to_a[5]
p, n = current_record.proximal_records(scope) # will find record 5 and 7

【讨论】:

【参考方案7】:

您实际上只需要运行 2 个查询,“prev”和“next”各一个。假设您有一个 created_at 列。

伪代码:

# get prev
select * from posts where created_at < #this_post.created_at order by created_at desc limit 1

# get next
select * from posts where created_at > #this_post.created_at order by created_at desc limit 1

“this_post”当然是当前帖子。

如果您的帖子使用 auto_increment 列存储并且您不重复使用 ID,则可以使用 id 列代替 created_at - id 列应该已经被索引。如果您想使用 created_at 列,那么您肯定希望在该列上有一个索引。

【讨论】:

是的,你是对的,需要订购。我更新了我的回复。 谢谢!但如果需要检测下一个或上一个字母:标题帖子?

将类添加到wordpress中的上一篇文章和下一篇文章中

add_filter('next_posts_link_attributes','posts_link_attributes');add_filter('previous_posts_link_attributes','posts_link_attributes'); functionposts_link_attributes(){ return'class="styled-button"';} 查看详情

Rails:获取下一个/上一个记录

.../previousrecord【发布时间】:2011-09-1221:10:34【问题描述】:我的应用有属于用户的照片。在photo#show视图中,我想显示“来自该用户的更多信息”,并显示该用户的下一张和上一张照片。我可以将这些作为id订单中的下一张/上一张... 查看详情

Rails 3:在视图中显示来自控制器的变量

...我对Rails很陌生,我想知道如何将控制器中的变量显示到我的视图中。基本上,我有2个文件:articles_controller.rb和_article.html.erb在我的控制器文件中,我有一个变量@article_votes,我 查看详情

如何使用 Mongoose 获取当前项的下一项和上一项

...:我有一个博客。在单个帖子页面上,我想显示指向上一篇文章的链接,如果有,则在底部发布下一篇文章。链接应该是特定帖子的标题。如何使用Mongoose以最简单的方式做到这一点?我当前的控制器如下所示:Po 查看详情

如何使用 Mongoose 获取当前项的下一项和上一项

...:我有一个博客。在单个帖子页面上,我想显示指向上一篇文章的链接,如果有,则在底部发布下一篇文章。链接应该是特定帖子的标题。如何使用Mongoose以最简单的方式做到这一点?我当前的控制器如下所示:Po 查看详情

在 Rails 视图中显示虚拟字段

.../postgis-and-rails-a-simple-approach.html),以便可以根据距离显示我的应用中的搜索结果。我列出了所有任务及其相关的项目信息-一个项目可以有多个任务。我的Pr 查看详情

织梦正则自定义输出电脑站移动站上一篇下一篇文章(代码片段)

不去修改程序文件,用标签和正则直接在内容页模板里直接输出上一篇下一篇的链接和标题和没有上一篇下一篇的提示文字电脑站上一篇下一篇的链接<li><ahref="dede:prenextget=prerunphp=yes$url=@me;preg_match(‘/href=[‘"]?([^‘"]+)/‘,$... 查看详情

CSV上传显示故障Rails 6

...图或只是原始数组视图而不是html/css它应该进去吧。这是我的代码:<table><thead> 查看详情

在 Ruby on Rails 中检查视图中的 nil

...段时间了,我发现自己经常做的一件事是在显示之前检查我的视图代码中的某些属性或对象是否为nil。我开始怀疑这是否总是最好的主意。到目前为止,我的理由是,由于我的应用程序依赖于用户输入,因此可能会发生意外的事... 查看详情

内存中的对象可以在 Rails 中进行关联吗?非传统形式视图

...我在Rails视图中提交和显示数据时遇到结构性问题。对于我的项目创建视图,用户可以向项目添加技能要求。但是,该项目仅存在于内存中,因此当我在技能控制器的创建操作中为其分配技 查看详情

Rails 如何转义和显示渲染视图的内容

】Rails如何转义和显示渲染视图的内容【英文标题】:RailsHowtoescapeanddisplaythecontentsofarenderedview【发布时间】:2010-10-2521:08:30【问题描述】:我正在尝试在文本区域中显示Rails视图文件。视图文件包含一堆HTML,我想将其转义,以免... 查看详情

无法访问 json 对象属性和值在 rails 视图中显示为未定义

...2018-09-0516:21:15【问题描述】:我几乎看过类似的问题,但我的问题还没有解决。我有以下代码。控制器defcreate@task_list=TaskList.new(task_list_param 查看详情

Rails 4:条件显示在视图内不起作用

...nginsideview【发布时间】:2015-10-2300:42:00【问题描述】:在我的Rails4应用程序中,有一个Post模型,具有:copy和:short_copy属性。在Posts#Show视图中,如果:short_copy由用户定义,我想显示它,否则:copy。所以,我实现了以下代码:<%if@p 查看详情

删除视图 Rails 中的重复项

...:41:33【问题描述】:这里有个小问题,也许很简单。假设我的数据库返回重复项。例如,我有多个包含不同开始和结束时间的房间。我当前的视图如下:<table><thead><tr><th>Location</th><th>Status 查看详情

在链接到 Rails 中的模型视图时需要一些帮助

...itPoints、ArmorClass等。这些都是从字符视图中构建、编辑和显示的。但是,我想创建 查看详情

仅在 Rails 中搭建视图文件。可能的?

...后,我在Books数据库表中添加了几列。因为我实际上希望我的视图能够反映和显示与所有这些新添加的列相关的字段,所以我认为删除views/books/文件夹中的所有内容并让一些脚手架代码从头开始重新生成它会更便宜。我不想删除 查看详情

Rails 中的高级/基本和智能手机视图

】Rails中的高级/基本和智能手机视图【英文标题】:advance/basicandsmartphoneviewsinRails【发布时间】:2010-06-1813:49:48【问题描述】:在一个新的Rail应用程序中,我必须考虑2种不同的用户类型:基本和高级我必须创建智能手机视图(... 查看详情

如何在 Ruby on Rails 视图中显示国家代码和电话号码的最后 3 位数字?

...这是原来的电话号码+77123456999我将其显示为+77xxxxxx999这是我的index.html.erb文件代码。& 查看详情