จะส่งความคิดเห็น Polymorphic บนฟีดได้อย่างไร [ข้อผิดพลาด]

หากผู้ใช้คลิกปุ่ม [+ ความคิดเห็น]

ป้อนคำอธิบายรูปภาพที่นี่

เขากำลังเผชิญหน้ากับสัตว์ร้ายตัวนี้:

ActiveRecord::RecordNotFound in CommentsController#create
Couldn't find Comment with 'id'=
Line: @commentable = resource.singularize.classify.constantize.find(id)

กิจกรรม/ดัชนี

<%= link_to activity.user.name, activity.user %>
<%= render "activities/#{activity.trackable_type.underscore}/#{activity.action}", activity: activity %>
<%= render "comments/comments", comments: activity.comments %>
<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name) %>

ความคิดเห็น/_ฟอร์ม

<%= form_for new_comment do |f| %>
  <%= f.text_area :content, rows: 4, class: 'form-control', placeholder: 'Enter Comment' %>
  <%= button_tag(type: 'submit', class: "btn") do %>
    <span class="glyphicon glyphicon-plus"></span> Comment
  <% end %>
<% end %>

กิจกรรม_ตัวควบคุม

def index
  @activities = Activity.order("created_at desc").where(user_id: current_user.following_ids)
  @commentable = @activity
  @comment = Comment.new
end

ข้อผิดพลาดสามารถพบได้ที่นี่:

class CommentsController < ApplicationController
  before_action :load_commentable
  before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]
  before_action :logged_in_user, only: [:create, :destroy]

    def index
        @comments = @commentable.comments
    end

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

    def create
        @comment = @commentable.comments.new(comment_params)
        if @comment.save
            redirect_to @commentable, notice: "comment created."
        else
            render :new
        end
    end

    def edit
        @comment = current_user.comments.find(params[:id])
    end

    def update
        @comment = current_user.comments.find(params[:id])
        if @comment.update_attributes(comment_params)
            redirect_to @commentable, notice: "Comment was updated."
        else
            render :edit
        end
    end

    def destroy
        @comment = current_user.comments.find(params[:id])
        @comment.destroy
        redirect_to @commentable, notice: "comment destroyed."
    end

  def like
    @comment = Comment.find(params[:id])
    @comment_like = current_user.comment_likes.build(comment: @comment)
    if @comment_like.save
            @comment.increment!(:likes)
        flash[:success] = 'Thanks for liking!'
    else
        flash[:error] = 'Two many likes'
      end  
        redirect_to(:back)
  end

private
  def set_comment
    @comment = Comment.find(params[:id])
  end

    def load_commentable
        resource, id = request.path.split('/')[1, 2]
        @commentable = resource.singularize.classify.constantize.find(id) #Here it is!
    end

    def comment_params
        params[:comment][:user_id] = current_user.id
        params.require(:comment).permit(:content, :commentable, :user_id, :like)
    end
end

ข้อผิดพลาดมาจากคำตอบที่นี่: วิธีเพิ่มความคิดเห็น Polymorphic ฟีด?

การพัฒนา.บันทึก

Started POST "/comments" for ::1 at 2015-04-23 20:12:14 -0400
Processing by CommentsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"hU1lxg2BMqSyBo8j2SGiEB4wZ3ez5kz/E64mp6ssbwBnh+DddyTtNQxY+IYCluHHvs2wIBxrtD5hQVA5sGtXBg==", "comment"=>{"content"=>"test"}, "button"=>""}
  [1m[35mUser Load (0.2ms)[0m  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 2]]
  [1m[36mHabit Load (0.1ms)[0m  [1mSELECT "habits".* FROM "habits" WHERE "habits"."user_id" = ?[0m  [["user_id", 2]]
  [1m[35mHabit Load (2.5ms)[0m  SELECT "habits".* FROM "habits"
  [1m[36mActsAsTaggableOn::Tag Load (0.3ms)[0m  [1mSELECT "tags".* FROM "tags" WHERE (LOWER(name) = LOWER('ingrain'))[0m
  [1m[35mComment Load (0.3ms)[0m  SELECT  "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT 1  [["id", nil]]
Completed 404 Not Found in 16ms

ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'=):
  app/controllers/comments_controller.rb:61:in `load_commentable'

ขอบคุณมาก!


person AnthonyGalli.com    schedule 22.04.2015    source แหล่งที่มา
comment
ฉันขอถามได้ไหมว่าคุณพยายามทำอะไรกับบรรทัดนั้น? ดูเหมือนว่าจะได้ผลถึง Comment.find(id) ถ้าเป็นเช่นนั้น คุณช่วยลดความซับซ้อนได้ไหม? แยกประเด็นหลักคือ @commentable สามารถเป็นศูนย์ได้ และคุณไม่ได้ป้องกันสิ่งนั้นจากสิ่งที่ฉันเห็น   -  person steve klein    schedule 24.04.2015
comment
เฮ้ @steveklein ใช่ ฉันคิดว่าเราสามารถลดความซับซ้อนของสิ่งที่จะให้: undefined local variable or method 'id ฉันได้รับโค้ดจาก Railscasts ตอนนี้: railscasts.com/episodes/154-polymorphic-association -แก้ไขแล้ว นอกจากนี้เขายังเสนอทางเลือกอื่น: def load_commentable klass = [Valuation].detect { |c| params["#{c.name.underscore}_id"]} @commentable = klass.find(params["#{klass.name.underscore}_id"]) end ซึ่งจะให้ undefined method 'name' for nil:NilClass สำหรับบรรทัดที่ 2   -  person AnthonyGalli.com    schedule 24.04.2015
comment
เราจำเป็นต้องกำหนดชื่อของทรัพยากรที่สามารถแสดงความคิดเห็นได้และรหัสของมัน เราจะได้สิ่งเหล่านี้จาก request.path โดยแยกมันทุกๆ เครื่องหมายทับและดึงองค์ประกอบที่สองและสาม ดังนั้นหากเส้นทางคือ /values/1 สิ่งเหล่านี้จะเป็นสององค์ประกอบที่ใช้ เราสามารถใช้สิ่งเหล่านี้เพื่อตั้งค่า @commentable โดยการเรียก singlularize.classify.constantize เพื่อรับคลาสของโมเดลและเรียก find เพื่อรับอินสแตนซ์ด้วย id ไม่แน่ใจว่าจะแก้ไขอย่างไร @steveklein   -  person AnthonyGalli.com    schedule 24.04.2015


คำตอบ (2)


ปัญหาคือเพื่อให้ใช้งานได้ ดูเหมือนว่ามีการตั้งค่าความคิดเห็นให้เป็นทรัพยากรที่ซ้อนกันของสิ่งที่คุณแสดงความคิดเห็นในไฟล์เส้นทางของคุณ

ดังนั้น หากคุณต้องการแสดงความคิดเห็นเกี่ยวกับกิจกรรม คุณจะต้องมี:

resources :activites do
  resources :comments
end

ด้วยวิธีนี้ เมื่อเมธอด #load_commentable แยกเส้นทางคำขอ ก็จะได้รับความคิดเห็นและรหัสจากสองส่วนแรก

ดูเหมือนว่าคุณกำลังพยายามใช้ความคิดเห็นเป็นแหล่งข้อมูลระดับบนสุดแทน

อัปเดต: เมื่อคุณเรียกบางส่วนของคุณ เพียงส่งต่อตัวช่วย url ที่แบบฟอร์มควรใช้ แบบนี้:

<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name), create_url: :activity_comments_path %>

จากนั้นในบางส่วน เพียงเรียกใช้ตัวช่วยนั้นและส่งผลลัพธ์เป็นตัวเลือก url เช่นนี้

<%= form_for new_comment, url: send(create_url, new_comment.commentable)
person Joe Martinez    schedule 24.04.2015
comment
ฉันมีสิ่งนั้นอยู่แล้ว แต่ฉันก็มีมันเป็นทรัพยากรระดับบนสุดด้วย ฉันลบมันออกจากการเป็นทรัพยากรระดับบนสุด และตอนนี้ฉันได้รับข้อความแสดงข้อผิดพลาด: undefined method 'comments_path' for ... บรรทัด: <%= form_for new_comment do |f| %> ดังนั้นบางทีคุณอาจเข้าสู่บางสิ่งบางอย่าง - person AnthonyGalli.com; 24.04.2015
comment
เมื่อคุณส่งตัวแปรโลคัล new_comment ไปยังบางส่วน ให้ลองใช้เป็น Activity.comments.build - หากไม่ได้สร้างเส้นทางโดยใช้ตัวช่วยเส้นทางของทรัพยากรที่ซ้อนกัน คุณก็สามารถส่งต่อตัวช่วยเส้นทางที่คุณต้องการใช้ได้เช่นกัน - person Joe Martinez; 24.04.2015
comment
เฮ้ โจ มาร์ติเนซ เพิ่งแชทกับสตีฟเสร็จ เราไม่สามารถแก้ปัญหาได้ อาจจะเป็นไปไม่ได้. คุณยินดีที่จะแชท? ขอบคุณโจ! - person AnthonyGalli.com; 24.04.2015
comment
เป็นไปได้อย่างแน่นอน - คุณเพียงแค่ต้องผ่านตัวช่วยเส้นทางไปยังความคิดเห็นของคุณเพียงบางส่วน Stack Exchange มีฟังก์ชั่นแชทหรือไม่? - person Joe Martinez; 26.04.2015
comment
ใช่แล้ว บางทีคุณอาจช่วยฉันลองทำสิ่งนี้ก่อนที่ฉันจะยอมแพ้โดยสิ้นเชิง พบกับฉันที่นี่ถ้าคุณทำได้ Joe: chat.stackoverflow.com/rooms /76301/ ขอบคุณสำหรับความช่วยเหลือ! - person AnthonyGalli.com; 26.04.2015
comment
โจเวลาไหนที่เหมาะกับคุณ? คุณเปลี่ยนใจเกี่ยวกับการแชทหรือไม่? ขออภัยในความพากเพียร ฉันแค่อยากทำให้สิ่งนี้สำเร็จ - เป็นความหวังสุดท้ายของฉัน :/ - person AnthonyGalli.com; 29.04.2015
comment
ดูเหมือนว่าเราจะไม่ได้ออนไลน์ในเวลาเดียวกันเลย - ฮ่าๆ หากคุณโพสต์มุมมองและส่วนสำคัญของคุณ ฉันจะแสดงให้คุณเห็นการเปลี่ยนแปลงที่ฉันคิดว่าจะแก้ไขได้ - person Joe Martinez; 29.04.2015
comment
ฉันอัปเดตตัวอย่างของฉันด้วยวิธีที่คุณจะส่งต่อตัวช่วย url เพื่อให้งานนี้สำเร็จ ตรวจสอบให้แน่ใจว่าคุณใช้เส้นทางแบบซ้อนที่ฉันอธิบายไว้ในส่วนแรกของคำตอบด้วย ขอให้โชคดี! - person Joe Martinez; 29.04.2015

ใน load_commentable ก่อนการดำเนินการ คุณสามารถเปลี่ยนเส้นทางไปยังหน้าข้อผิดพลาดหรือบางอย่างหาก @commentable คือ nil ตามที่เป็นอยู่ คุณกำลังพยายามเข้าถึงคุณลักษณะของวัตถุ nil นี้ด้วยวิธีอื่น (create ในกรณีของข้อผิดพลาดนี้)

person steve klein    schedule 24.04.2015
comment
ฉันมีช่วงเวลาที่ยากลำบากในการใช้สิ่งที่คุณหมายถึง :/ ปัญหาอยู่ที่เมื่อฉันกดส่ง ดังนั้นทั้งหมดจะไม่มีค่าเลยหรือเพราะจำเป็นต้องบันทึกก่อน คุณกำลังแนะนำให้ฉันเพิ่มเงื่อนไขในบรรทัด before_action :load_commentable หรือไม่? ไม่เคยเห็น เลยคิดว่าเข้าใจผิดครับ ขอโทษนะสตีฟ - person AnthonyGalli.com; 24.04.2015
comment
คุณไม่คิดว่า @commentable จะใช้ได้ (ไม่ใช่ nil) เมื่อคุณ create a comment? คุณเพียงใช้ before_action เพื่อความสะดวก หากคุณต้องย้ายโค้ดนั้นเมื่อเริ่มต้นการดำเนินการที่ต้องพึ่งพาแต่ละอย่าง คุณจะไม่มีทางดำเนินการกับวัตถุ nil ที่อาจเป็นไปได้ นั่นคือเหตุผลที่ฉันไม่ชอบใช้ before_action ในลักษณะนี้ - มันไม่โปร่งใสมากนัก ในตอนท้ายของ load_commentable คุณสามารถเพิ่ม redirect_to root_path if @commentable == nil ได้ เราสามารถตั้งค่าการแชทได้หากจำเป็น - person steve klein; 24.04.2015
comment
มาทำกันเถอะ! ฉันประสบปัญหากับความคิดเห็นล่าสุดของคุณ ต้องการพบฉันที่นี่: chat.stackoverflow.com/rooms/76194/? - person AnthonyGalli.com; 24.04.2015