Rails仅迭代与对象关联的持久记录

我的show动作中有这样的东西:

 def show @blog = Blog.find(params[:id]) @new_comment = @blog.comments.build end 

现在在视图中我做了两件事:

  1. 我为Comment渲染_form.html.erb ,以便用户可以向此博客添加评论
  2. 我希望能够遍历此博客的现有评论,以便显示它们。

我遇到了2号问题。 问题在于,当我用以下方法迭代相关的comments时:

  

在迭代关联的博客时,它抓住了@new_comment 。 如何排除那些内置但尚未持久化的@new_comment

如果像@blog.comments.each_with_id这样的东西工作,甚至@blog.comments.persisted.each 。 最后,我只想迭代与此blog相关的持久性comments

我宁愿不必嵌套条件,询问评论是否persisted? 。 我希望我的当前情况有一个迭代器可以抓住持久化的记录。

如果在不使用与博客实例的关联的情况下创建新注释,该怎么办? 然后,当您遍历@blog.comments时,它不会显示出来。

 def show @blog = Blog.find(params[:id]) @new_comment = Comment.new(blog: @blog) end 

在你的视图循环中,你可以跳过if comment.new_record?

 <% @blog.comments.each do |comment| %> <% next if comment.new_record? %> 

根据您的评论编辑:

如果您不希望在迭代期间过滤掉,则可以在迭代之前拒绝新记录。 但是,我不推荐这种方法,因为你创建一个全新的记录数组,没有什么理由。 假设博客没有成千上万的评论,你的表现真的很受欢迎,但它仍然不是一个很好的做法。

 <% @blog.comments.reject(&:new_record?).each do |comment| %> 

如果你真的想要将逻辑与视图和控制器分开,你可以在构建新的逻辑之前创建另一个完全专用于博客评论的变量,以便在迭代期间不包含它。

 # controller def show @blog = Blog.find(params[:id]) @current_comments = @blog.comments @new_comment = @blog.comments.build end #view <% @current_comments.each do |comment| %> 

为了它的价值,我仍然推荐第一个apprach

您可以在Comment模型中添加一个类方法,例如:

 def self.persisted reject { |comment| comment.new_record? } end 

然后打电话

 @blog.comments.persisted 

缺点是在此之后你不再拥有ActiveRecord::Relation并且可能会破坏你的范围链。 确保在ActiveRecord查询中最后使用它。