我一直在尝试修复与使用Ancestry gem相关的错误,以便对我的Rails 4应用程序发表评论。我使用railscast episode 262作为指南。但是,与剧集不同,我的评论模型是另一个模型中的嵌套资源。在我走得更远之前,我将提供必要的代码供参考。如果您想立即阅读错误,请在所有代码段后面提及。
相关模型:
class Comment < ActiveRecord::Base
has_ancestry
belongs_to :user
belongs_to :scoreboard
end
class Scoreboard < ActiveRecord::Base
#scoreboard model is like an article page on which users can post comments
belongs_to :user
has_many :teams, dependent: :destroy
has_many :comments, dependent: :destroy
end
路线文件中的相关代码:
resources :scoreboards do
resources :comments
resources :teams, only: [:edit, :create, :destroy, :update]
end
记分板控制器方法,用于发布评论的页面:
def show
@scoreboard = Scoreboard.find_by_id(params[:id])
@team = @scoreboard.teams.build
@comment = @scoreboard.comments.new
end
评论总监:
class CommentsController < ApplicationController
def new
@scoreboard = Scoreboard.find(params[:scoreboard_id])
@comment = @scoreboard.comments.new(:parent_id => params[:parent_id])
end
def create
@scoreboard = Scoreboard.find(params[:scoreboard_id])
@comment = @scoreboard.comments.new comment_params
if @comment.save
redirect_to scoreboard_url(@comment.scoreboard_id)
else
render 'new'
end
end
private
def comment_params
params.require(:comment).permit(:body, :parent_id).merge(user_id: current_user.id)
end
end
如果对此有任何错误,我将包括祖先gem的迁移:
class AddAncestryToComments < ActiveRecord::Migration
def change
add_column :comments, :ancestry, :string
add_index :comments, :ancestry
end
end
以下代码显示了视图代码:
记分牌#show查看,它在最后一行给出了错误:
<div class= "comment-section">
<%= form_for [@scoreboard, @comment] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_area :body, class: "comment-field" %>
<%= f.hidden_field :parent_id %> #is it needed to include this here? because this form is for new comments not replies
<%= f.submit "Join the discussion...", class: " comment-button btn btn-primary" %>
<% end %>
<%= nested_comments @scoreboard.comments.reject(&:new_record?).arrange(:order => :created_at) %>
</div>
(评论部分)_comment.html.erb查看:
<div class=" comment-div">
<p> Posted by <%= link_to "#{comment.user.name}", comment.user %>
<%= time_ago_in_words(comment.created_at) %> ago
</p>
<div class="comment-body">
<%= comment.body %>
<%= link_to "Reply", new_scoreboard_comment_path(@scoreboard, comment, :parent_id => comment) %>
</div>
</div>
呈现注释的辅助方法:
def nested_comments(comments)
comments.map do |comment, sub_comment| #the comments.map also gives me an error if I choose to render the comments without the .arrange ancestry method
render(comment) + content_tag(:div, nested_comments(sub_comment), class: "nested_messages")
end.join.html_safe
end
用于评论的new.html.erb,其中一个被重定向到回复表单提交:
<%= form_for [@scoreboard, @comment] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_area :body, class: "comment-field" %>
<%= f.hidden_field :parent_id %>
<%= f.submit "Join the discussion...", class: " comment-button btn btn-primary" %>
<% end %>
创建记分牌后,我被重定向到显示页面,我收到以下错误:
未定义的方法`安排&#39; for []:Array
即使注释数组为空,如果不是,我也会得到相同的错误。我尝试了 .subtree.arrange ,但这给了我同样的错误。此外,祖先文档说.arrange仅适用于作用域类。我不知道这意味着什么。我希望有一些关于使页面工作的帮助,以便评论显示在他们的父评论之后与回复一起正确排序。如果这是线程评论(回复和所有)的错误方法,我将非常感谢下一步研究的一些指导。
答案 0 :(得分:2)
.reject(&:new_record?)
这将返回一个数组。这个错误听起来像是ActiveRecord上的一个范围。所以将reject
移到最后,它应该可以工作。
@scoreboard.comments.arrange(:order => :created_at).reject(&:new_record?)
答案 1 :(得分:1)
关于你的评论嵌套,我之前已经实现了这一点,并且发现帮助的Railscasts建议非常弱。
相反,根据每个comment
的子女数量,您可以更好地使用部分变为递归的部分:
#app/views/scoreboards/show.html.erb
<%= render @comments %>
#app/views/scoreboards/_comment.html.erb
<%= link_to comment.title, comment_path(comment) %>
<div class="nested">
<%= render comment.children if comment.has_children? %>
</div>