Rails仅迭代与对象关联的持久记录
我的show
动作中有这样的东西:
def show @blog = Blog.find(params[:id]) @new_comment = @blog.comments.build end
现在在视图中我做了两件事:
- 我为
Comment
渲染_form.html.erb
,以便用户可以向此博客添加评论 - 我希望能够遍历此博客的现有评论,以便显示它们。
我遇到了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
查询中最后使用它。