停止在@comments 的显示页面上显示评论表单的新@comment - Rails

Stop new @comment for comment form displaying on show page in @comments - Rails

您好,我是 Rails 的新手,我正在为我的 Shop_Profile 模型设置评论。我正在使用 acts_as_commentable gem 来允许多态注释。我允许在个人资料显示页面上发表评论,因此我在同一页面上显示评论列表和新的评论表单。

我在 ShopProfilesController 中的显示操作如下所示:

def show
    @comments = @shop_profile.comments
    @comment = @shop_profile.comments.new
  end

我在显示视图中呈现评论表单和评论:

<% if user_signed_in? %>
    <%= render 'comments/form' %>
<% end %>

<%= render @comments %>

我在评论控制器上的创建操作是:

def create
    @comment = @user.comments.build(comment_params)
    @commentable = Comment.find_commentable(params[:comment][:commentable_type], params[:comment][:commentable_id])

    if @comment.save
      redirect_to @commentable
    end
  end

我的 _comment 部分是:

<p>
  <strong>Title:</strong>
  <%= comment.title %>
</p>

<p>
  <strong>Comment:</strong>
  <%= comment.comment %>
</p>

<p>
  <small>By:</small>
  <%= comment.user.username %>
</p>

表单的新@comment 不断包含在@comments 中,因此导致错误 "undefined method `username' for nil:NilClass" 因为新的@commentn 没有 user_id。 如何在不包含 form_for?

的新@comment 的情况下显示我的@comments

感谢您的帮助

您正在 collection 中创建附加评论,而该新评论还没有关联用户,也未保存在数据库中。

如果你想完全跳过新评论,你可以这样做:

<%= render @comments.reject{|c| c == @comment } %>

如果您希望显示新评论,但跳过 "By" 部分,您可以这样做:

<% if comment != @comment %>
  <p>
    <small>By:</small>
    <%= comment.user.username %>
 </p>
<% end %>

不幸的是(在这种情况下)new/build 将构建的对象添加到关联的集合中。因此,您需要声明您的意图,即您 想要将项目存储在数据库中以用于 @comments 集合。

你有两个选项我知道:

def show
  @comment = @shop_profile.comments.new
  @comments = @shop_profile.comments(true)
end

这会强制 @comments 干净地加载,因此它只会包含原始列表。不幸的是,您为同一个列表访问了数据库两次,这很愚蠢。

我认为更好的做法是:

def show
  @comments = @shop_profile.comments.to_a
  @comment = @shop_profile.comments.new
end

所以现在您通过将 @comments 集合从活动记录关联中分离出来,使它成为一个数组,所以稍后的 new 调用不会修改您仍然保留的任何内容。