无法使用 Ancestry gem(ruby on rails)为嵌套评论分配父 ID
Unable to assign a parent id to nested comments, using Ancestry gem (ruby on rails)
我正在创建嵌套评论(就像你在 Reddit 上看到的那样)。我能够创建父评论,但是当我尝试创建子评论时,它只是呈现为父评论。
在我的 rails 控制台中,"ancestry" 字段返回 "nil"。
这是我的评论管理员:
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!
def show
@comment = Comment.find(params[:id])
end
def new
@link = Link.find(params[:link_id])
@comment = Comment.new(:parent_id => params[:parent_id])
@comments = Comment.all
end
def create
@link = Link.find(params[:link_id])
@parent = Link.find(params[:link_id]) if params[:link_id]
@parent = Comment.find(params[:comment_id]) if params[:comment_id]
@comment = @parent.comments.new(comment_params)
@comment.user = current_user
respond_to do |format|
if @comment.save
format.html { redirect_to @link, notice: 'Comment was successfully created.' }
format.json { render json: @comment, status: :created, location: @comment }
else
format.html { render action: "new" }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
@comment.destroy
respond_to do |format|
format.html { redirect_to :back, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_comment
@comment = Comment.find(params[:id])
end
def comment_params
params.require(:comment).permit(:link_id, :body, :user_id)
end
end
这是我的_comment_form部分
<%= div_for(comment) do %>
<div class="comments_wrapper clearfix">
<div class="pull-left">
<p class="lead"><%= comment.body %></p>
<p><small>Submitted <strong><%= time_ago_in_words(comment.created_at) %> ago</strong> by <%= comment.user.email %></small></p>
<div id="reply" style="display:none;">
<%= form_for [@comment = Comment.new(:parent_id => params[:parent_id])] do |f| %>
<%= f.hidden_field :parent_id %>
<%= f.text_area :body %> <br>
<%= f.submit %>
<% end %>
</div>
</div>
<div class="actions btn-group pull-right">
<button onClick="$('#reply').show()" class="btn btn-sm btn-default">Reply</button>
<% if comment.user == current_user -%>
<%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-sm btn-default" %>
<% end %>
</div>
</div>
<% end %>
这些是我的路线
Rails.application.routes.draw do
resources :comments
devise_for :users
devise_for :installs
resources :links do
member do
put "like", to: "links#upvote"
put "dislike", to: "links#downvote"
end
resources :comments
end
root to: "links#index"
end
以前遇到过这个问题;答案在这里:
Ancestry gem in Rails and Mutli Nesting
ancestry
(this is why we changed back to acts_as_tree
) 的问题是您必须 在 ancestry
列中定义所有祖先 (与 相对)只是 acts_as_tree
的 parent_id
列。
因此,当您调用 object 的 .children
时(您实际上只是用 top-level parent 填充 ancestry
)是children 的 that parent 的列表(没有其他)。
您需要的是引用整个祖先系。这非常棘手,但可以使用以下代码实现:
#app/views/links/index.html.erb
<%= render @link.comments if @post.comments.any? %>
#app/views/links/_comment.html.erb
<%= comment.title %>
<%= render "form", locals: {link: @link} %>
<%= render comment.children if comment.has_children? # > adds recursion (multi level nesting) %>
#app/views/links/_form.html.erb
<%= form_for link.comments.new do |c| %>
<%= c.text_field :body %>
<%= c.submit %>
<% end %>
控制器如下:
#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@link = Link.find params[:link_id]
@comment = @link.comments.new ancesrtry: parent(params[:parent_id])
end
private
def parent(param)
parents = Comment.find(param).pluck(:parent)
"#{parents}/#{param}" #-> ruby automatically returns last line
end
end
这应该为您设置正确的路径,部分应该为您提供多层嵌套所需的适当递归。
我正在创建嵌套评论(就像你在 Reddit 上看到的那样)。我能够创建父评论,但是当我尝试创建子评论时,它只是呈现为父评论。
在我的 rails 控制台中,"ancestry" 字段返回 "nil"。
这是我的评论管理员:
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!
def show
@comment = Comment.find(params[:id])
end
def new
@link = Link.find(params[:link_id])
@comment = Comment.new(:parent_id => params[:parent_id])
@comments = Comment.all
end
def create
@link = Link.find(params[:link_id])
@parent = Link.find(params[:link_id]) if params[:link_id]
@parent = Comment.find(params[:comment_id]) if params[:comment_id]
@comment = @parent.comments.new(comment_params)
@comment.user = current_user
respond_to do |format|
if @comment.save
format.html { redirect_to @link, notice: 'Comment was successfully created.' }
format.json { render json: @comment, status: :created, location: @comment }
else
format.html { render action: "new" }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
@comment.destroy
respond_to do |format|
format.html { redirect_to :back, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_comment
@comment = Comment.find(params[:id])
end
def comment_params
params.require(:comment).permit(:link_id, :body, :user_id)
end
end
这是我的_comment_form部分
<%= div_for(comment) do %>
<div class="comments_wrapper clearfix">
<div class="pull-left">
<p class="lead"><%= comment.body %></p>
<p><small>Submitted <strong><%= time_ago_in_words(comment.created_at) %> ago</strong> by <%= comment.user.email %></small></p>
<div id="reply" style="display:none;">
<%= form_for [@comment = Comment.new(:parent_id => params[:parent_id])] do |f| %>
<%= f.hidden_field :parent_id %>
<%= f.text_area :body %> <br>
<%= f.submit %>
<% end %>
</div>
</div>
<div class="actions btn-group pull-right">
<button onClick="$('#reply').show()" class="btn btn-sm btn-default">Reply</button>
<% if comment.user == current_user -%>
<%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-sm btn-default" %>
<% end %>
</div>
</div>
<% end %>
这些是我的路线
Rails.application.routes.draw do
resources :comments
devise_for :users
devise_for :installs
resources :links do
member do
put "like", to: "links#upvote"
put "dislike", to: "links#downvote"
end
resources :comments
end
root to: "links#index"
end
以前遇到过这个问题;答案在这里:
Ancestry gem in Rails and Mutli Nesting
ancestry
(this is why we changed back to acts_as_tree
) 的问题是您必须 在 ancestry
列中定义所有祖先 (与 相对)只是 acts_as_tree
的 parent_id
列。
因此,当您调用 object 的 .children
时(您实际上只是用 top-level parent 填充 ancestry
)是children 的 that parent 的列表(没有其他)。
您需要的是引用整个祖先系。这非常棘手,但可以使用以下代码实现:
#app/views/links/index.html.erb
<%= render @link.comments if @post.comments.any? %>
#app/views/links/_comment.html.erb
<%= comment.title %>
<%= render "form", locals: {link: @link} %>
<%= render comment.children if comment.has_children? # > adds recursion (multi level nesting) %>
#app/views/links/_form.html.erb
<%= form_for link.comments.new do |c| %>
<%= c.text_field :body %>
<%= c.submit %>
<% end %>
控制器如下:
#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@link = Link.find params[:link_id]
@comment = @link.comments.new ancesrtry: parent(params[:parent_id])
end
private
def parent(param)
parents = Comment.find(param).pluck(:parent)
"#{parents}/#{param}" #-> ruby automatically returns last line
end
end
这应该为您设置正确的路径,部分应该为您提供多层嵌套所需的适当递归。