【发布时间】:2017-11-21 06:03:02
【问题描述】:
我正在尝试为 Question 和 Answer 创建多态 cmets,但是当我点击“创建评论”表单上的“创建”按钮时,commentable_type 和 commentable_id 从未通过。我可以通过 rails 控制台成功创建新评论,但不能通过表单(目前我正在测试 cmets 的问题)。我在 cmets_controller 的 load_commentable 或 create 中遇到错误,例如:
NoMethodError (undefined method `comments' for nil:NilClass):
app/controllers/comments_controller.rb:9:in `create'
似乎@commentable 是nil(因为它没有得到commentable_type 和commentable_id 参数?)。
我错过了什么?
cmets 迁移:
class CreateComments < ActiveRecord::Migration[5.1]
def change
create_table :comments do |t|
t.references :user, foreign_key: true
t.text :body, null:false
t.references :commentable, polymorphic: true, index: true
t.timestamps
end
add_index :comments, [:commentable_id, :commentable_type]
end
end
routes.rb:
Rails.application.routes.draw do
resources :comments, only: [:create]
resources :votes, only: [:create] do
delete :reset, on: :collection
end
resources :attachments, only: :destroy
devise_for :users
resources :questions do
resources :comments, only: :create, defaults: { commentable: 'questions' }
resources :answers, shallow: true do
resources :comments, only: :create, defaults: { commentable: 'answers' }
patch :set_best, on: :member
end
end
root to: "questions#index"
mount ActionCable.server => '/cable'
end
cmets 表单部分 _comment_form.html.slim:
h4 Add a comment
.comment_errors
= form_for [@commentable, Comment.new], remote: true do |f|
.form-group
= f.label :body, 'Comment'
= f.text_area :body, class: 'form-control'
p= f.submit 'Create', class: 'btn btn-primary'
cmets_controller:
class CommentsController < ApplicationController
before_action :authenticate_user!
before_action :load_commentable, only: [:create]
def create
@comment = @commentable.comments.create(comment_params.merge(user: current_user))
end
private
def load_commentable
if params[:comment][:commentable_type] == 'Answer'
@commentable = Answer.find(params[:comment][:commentable_id])
gon.answer_id = @commentable.id
elsif params[:comment][:commentable_type] == 'Question'
gon.answer_id = @commentable.id
@commentable = Question.find(params[:comment][:commentable_id])
end
end
def comment_params
params.require(:comment).permit(:body, :commentable_type, :commentable_id )
end
end
相关的 cmets 部分的显示视图:
h3 Comments
.question_comments id="comments_section_question_#{@question.id}"
- if user_signed_in?
.row
= render 'comments/comment_form', commentable: @question
错误日志:
app/controllers/comments_controller.rb:7:in `create'
Started POST "/comments" for 10.0.2.2 at 2017-11-20 20:54:42 +0000
Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by CommentsController#create as JS
Parameters: {"utf8"=>"✓", "comment"=>{"body"=>"kkkk"}, "commit"=>"Create"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 41], ["LIMIT", 1]]
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.4ms)
NoMethodError (undefined method `comments' for nil:NilClass):
app/controllers/comments_controller.rb:7:in `create'
【问题讨论】:
-
查看您的
params:"comment"=>{"body"=>"kkkk"}。看到有什么遗漏吗?然后看看你的表格。您有@commentable,但您在哪里将其值添加到表单中? -
id、user_id、commentable_type 和 commentable_id 参数丢失,但我不明白为什么以及如何解决此问题
-
Google for
hidden_field...顺便说一句,我不知道id指的是什么。但我想你不需要user_id,因为你可以通过设计获得它(我认为类似于current_user.id。但是,我不使用设计,所以这可能不完全正确)。 -
id 是评论的 id。我之前尝试过隐藏字段,但这不起作用并给出了类似的错误,我还了解到更好的解决方案是在控制器中动态传递这些字段,但无法修复代码。
标签: ruby-on-rails polymorphic-associations