在Rails 5中为文章添加注释(深层嵌套资源)

时间:2017-07-06 07:38:11

标签: ruby-on-rails

我有一个Rails应用程序,它有三个主要模型: Qn,Ans和Comments 。我已经使用1级深度嵌套资源做得很好,但是这三个资源是深度嵌套(注释是浅层嵌套的)并且它们都显示在一个单独的视图中< / em>,这让它非常混乱。

在类似:http://localhost:3000/questions/2的网址中,用户可以看到使用循环显示的所有 @ question.answers 。在每个答案中,用户可以看到使用循环显示的 answer.comments 。在每个答案下方,用户还可以提交新评论。

但是在尝试多次实现1)循环显示所有注释和2)表单的新评论后,我总是得到一些错误:

undefined method `model_name' for {:url=>"/questions/4/answers/2/comments/new"}:Hash

所以我尝试传递参数 @commentable 而不是回答,或指向特定控制器和操作等等,但这些方法都没有奏效。我猜我的控制器开头有问题,但我似乎无法弄清楚是什么。

routes.rb(top ommited)

# Resources
resources :sessions
resources :users
resources :bookmarks # to be implemented later

resources :questions do
  resources :answers do
    resources :comments, shallow: true
  end
end

问题模型

class Question < ApplicationRecord    
  has_many :answers
  has_many :bookmarks #later
end

答案型号:

class Answer < ApplicationRecord
  belongs_to :question
  has_many :comments, as: :commentable

  has_many :likes, as: :likeable
  validates :answercontent, length: {minimum: 50}
end

评论模型:

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

show.html.erb(QuestionsController)

<% @question.answers.each do |answer| %>
// ommited
<!-- Comments -->
<% answer.comments.each do |comment| %>
   <%= comment.content %>
   <br>
<% end %>

<!-- Submit new comment -->
<%= form_for(url: new_question_answer_comment_path, comment: {answer_id: answer.id, question_id: @question.id}) do |f| %>
   <%= f.text_area :content %>
   <%= f.submit "Submit" %>
<% end %>
<% end %>

QuestionsController(新的,创建,破坏为了简洁而省略)

class QuestionsController < ApplicationController
def index
    @questions = Question.all
end

def show
    @question = Question.find(params[:id])
    @answers = Answer.all

    # Delete only appears when num_ans is 0
    @deletable = (current_user== User.find(@question.user_id)) && (@question.answers.all.size==0)

end

private
  def question_params
    params.require(:question).permit(:picture_url, :country, :educational_level, :topic)
  end

end

AnswersController(为简洁起见,编辑,更新,销毁)

class AnswersController < ApplicationController

def create
    @question = Question.find(params[:question_id])
    @answer = @question.answers.create(answer_params)
    @answer.question_id = @question.id
    @answer.user_id = current_user.id

    if @answer.save
        redirect_to @question
    else
        render :new
    end
end

private
  def answer_params
    params.require(:answer).permit(:user_id, :question_id, :answercontent)
  end    
end

CommentsController

class CommentsController < ApplicationController
before_filter: load_commentable

def index
  @commentable = Answer.find(params[:answer_id])
  @comments = @commentable.comments
end

def new
   @comment = @commentable.comments.new
end

def create
  @comment = @commentable.comments.new(params[:comment])
    if @comment.save
     redirect_to @commentable
  else
    render :new
  end
end

# From RailsCast ep.154
private
def load_commentable
  resource, id = request.path.split('/')[1,2]
  @commentable = resource.singularize.classify.constantize.find(id)
end   
end

路线 现在很乱,所以我只会发表评论的地方:

 question_answer_comments GET    /questions/:question_id/answers/:answer_id/comments(.:format)     comments#index
                        POST   /questions/:question_id/answers/:answer_id/comments(.:format)     comments#create
new_question_answer_comment GET    /questions/:question_id/answers/:answer_id/comments/new(.:format) comments#new
           edit_comment GET    /comments/:id/edit(.:format)                                      comments#edit
                comment GET    /comments/:id(.:format)                                           comments#show
                        PATCH  /comments/:id(.:format)                                           comments#update
                        PUT    /comments/:id(.:format)                                           comments#update
                        DELETE /comments/:id(.:format)                                           comments#destroy

提前感谢您的帮助。

更新

为您提供有关我尝试的解决方案的更多信息: 1.传递两个参数:

<%= form_for([answer, @comment], url: new_question_answer_comment_path(answer.id, @question.id)) do |f| %>

给我:

First argument in form cannot contain nil or be empty
  1. 使用@commentable(基本上就是答案)给出了一个错误,指出@ commentable.id中的ID并不存在,因为@commentable是nil&#39;。
  2. 所以我认为问题是回答 @commentable 是零。但我也在循环和控制器中指定了它。那么我还能尝试什么呢?

1 个答案:

答案 0 :(得分:1)

form_for期望记录第一个参数,在您的情况下,它应该是评论实例。另外 new_question_answer_comment_path期望question_idanswer_id的值,因为您创建新评论 route < / em>应为question_answer_comments而不是new_question_answer_comment,因此您的form_for应为

<%= form_for Comment.new,url: question_answer_comments_path(@question,answer) do |f| %>
  <%= f.text_area :content %>
  <%= f.submit "Submit" %>
<% end %>

或只是

<%= form_for [Comment.new,@question,answer] do |f| %>
  <%= f.text_area :content %>
  <%= f.submit "Submit" %>
<% end %>