Ruby on Rails-无法嵌套评论

时间:2015-10-24 14:20:03

标签: ruby-on-rails ruby

我使用closure_tree gem为我的项目嵌套微博但它有错误。这是我的控制器:

def index
    @microposts = current_user.microposts.hash_tree
  end

  def new
    @micropost = current_user.microposts.build(parent_id: params[:parent_id])
  end

  def create
    if params[:micropost][:parent_id].to_i > 0
      parent = current_user.microposts.find_by_id(params[:micropost].delete(:parent_id))
      @micropost = parent.children.build(micropost_params) # error in here
    else
      @micropost = current_user.microposts.build(micropost_params)
    end
    if @micropost.save
      flash[:success] = 'Micropost created!'
      redirect_to root_url
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end
private

  def micropost_params
    params.require(:micropost).permit(:content, :picture)
  end
  # Returns the current logged-in user (if any).
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end
end

我无法回复任何微博。 首先,如果我回复自己,错误是“用户不能为空”。 其次,如果我回复任何用户微博,错误是“未定义的方法`孩子'为nil:NilClass”。 通常会创建微博。

1 个答案:

答案 0 :(得分:2)

首先,使用acts_as_tree - closure_tree是好的但不是很好,除了可能用于查询(closure_tree执行1次选择)。

-

无论如何,还有很多修复方法。我将详细说明我是如何做到的:

#app/models/micropost.rb
class Micropost < ActiveRecord::Base
   has_many :comments
end

#app/models/comment.rb
class Comment < ActiveRecord::Base
   belongs_to :micropost
   acts_as_tree #-> requires parent_id column in table
end 

这将为您提供模型中的相应设置。以下是如何在控制器中正确处理它:

#config/routes.rb
resources :microposts do
   resources :comments, only: [:create]
end

#app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
   def show
      @micropost = Micropost.find params[:id]
      @comment   = @micropost.comments.new
   end 
end

#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
   def create
      @micropost = Micropost.find params[:micropost_id]
      @comment   = @micropost.comments.new comment_params
      redirect_to @micropost if @comment.save
   end

   private

   def comment_params
      params.require(:comment).permit(:title, :body)
   end
end

这样您就可以展示Micropost&amp;视图中的Comments

#app/views/microposts/show.html.erb
<%= render @micropost %>

<%= render "comments/new" %>
<%= render @micropost.comments if @micropost.comments.any? %>

#app/views/microposts/_micropost.html.erb
<%= micropost.title %>
<%= micropost.body %>

#app/views/micropost/_comment.html.erb
<%= comment.title %>
<%= comment.body %>
<%= render @micropost.comments.children if @micropost.comments.children.any? %>

更新

感谢您的评论,如果你有完全相同的型号,你会想看看Single Table Inheritance

#app/models/micropost.rb
class Micropost < ActiveRecord::Base
   #columns id | type | parent_id | title | body | created_at | updated_at
   has_many :comments
end

#app/models/comment.rb
class Comment < Micropost
   #no table needed
   belongs_to :micropost
   acts_as_tree
end

我的上述代码将以完全相同的方式工作,除了现在将使用单个表。