2017-11-20 5 views
0

ich polymorphe Kommentare zu Question und Answer, aber commentable_type und commentable_id nie übergeben bekommen, wenn ich das auf die Schaltfläche „Erstellen“ getroffen erstellen bin versucht, Formular "Kommentar erstellen". Ich kann erfolgreich einen neuen Kommentar über die Rails-Konsole erstellen, aber nicht über das Formular (derzeit teste ich Kommentare für Fragen). Ich erhalte Fehler in load_commentable oder create von comments_controller, wie: (weil es nicht commentable_type und commentable_id params bekommt)Polymorphe Kommentare: nicht Art und id (NoMethodError für nil: NilClass) passieren kann

NoMethodError (undefined method `comments' for nil:NilClass): 

app/controllers/comments_controller.rb:9:in `create' 

Es scheint, dass @commentable ist nil. Was verpasse ich?

Migration für Kommentare:

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 

Kommentare bilden teilweise _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' 

comments_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 

Kommentaren in View zeigen Frage:

h3 Comments 
.question_comments id="comments_section_question_#{@question.id}" 
    - if user_signed_in? 
    .row 
     = render 'comments/comment_form', commentable: @question 

Fehlerprotokoll:

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' 
+1

Schauen Sie sich Ihre 'params':' "Kommentar" => { "body" => "kkkk "}". Siehst du etwas, das fehlt? Dann schau dir dein Formular an. Sie haben '@ commentable', aber wo fügen Sie seine Werte zum Formular hinzu? – jvillian

+0

id, user_id, commentable_type und commentable_id params fehlen, aber ich verstehe nicht warum und wie behebe ich das – Evanto

+1

Google für 'hidden_field' ... BTW, ich weiß nicht, was' id' sich bezieht. Aber ich stelle mir vor, du brauchst 'user_id' nicht, da du das über devise zur Verfügung hast (etwas wie' current_user.id', denke ich. Aber ich benutze kein Gerät, das ist vielleicht nicht genau richtig). – jvillian

Antwort

1

Ich denke, dass Ihr partial_comment_form.html.slim wie etwas sein sollte:

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' 
    = hidden_field_tag 'commentable[id]', @commentable.id 
    = hidden_field_tag 'commentable[type]', @commentable.class.name 
    p= f.submit 'Create', class: 'btn btn-primary' 

Welche Sie geben sollten params so etwas wie:

Parameters: {"utf8"=>"✓", "comment"=>{"body"=>"kkkk"}, "commentable"=>{"id"=>"1", "type"=>"Question"}, commit"=>"Create"} 

Dann ändern Sie load_commentable zu so etwas wie:

def load_commentable 
    @commentable = commentable_params[:type].constantize.find_by(id: commentable_params[:id]) 
    gon.answer_id = @commentable.id 
end 

(BTW, gon.answer_id wenn Sie eine Frage merkwürdig erscheint. Aber ich weiß nicht, ...)

Welche erfordert natürlich so etwas wie:

def commentable_params 
    param.require(:commentable).permit(:id, :type) 
end 
Verwandte Themen