Rails 4 — все вложенные полиморфные комментарии отображаются на каждой странице, а не на отдельных страницах

Я изучаю Rails и пытаюсь создать сайт с вложенными полиморфными комментариями.

Я следовал этому руководству http://www.tweetegy.com/2013/04/create-nested-comments-in-rails-using-ancestry-gem/, а также некоторые RailsCast (262-trees-with-ancestry и 154-polymorphic- ассоциация).

Мне удалось создать вложенные полиморфные комментарии (когда я проверяю консоль рельсов для каждого комментария). Однако проблема, с которой я сталкиваюсь, заключается в выводе комментариев. Все они отображаются на странице показа каждого ресурса, а не на соответствующей странице показа. Другими словами, все комментарии отображаются на /videos/1 и videos/2, и на уроках/1, и на уроках/3 (одни и те же комментарии отображаются на каждой странице).

Я подозреваю, что моя проблема в файле comments_helper.rb или /lib/commentable.rb, однако мне не удалось отладить проблему.

Маршруты

config/routes.rb

  devise_for :users

  resources :videos do
    resources :comments
  end

  resources :lessons do
    resources :comments
  end

Контроллеры

приложение/контроллеры/comments_controller.rb

class CommentsController < ApplicationController
  def new
    @parent_id = params.delete(:parent_id)
    @commentable = find_commentable
    @comment = Comment.new( :parent_id => @parent_id, 
                            :commentable_id => @commentable.id,
                            :commentable_type => @commentable.class.to_s)
  end

  def create
    @commentable = find_commentable
    @comment = @commentable.comments.build(comment_params)
    @comment.user_id = current_user.id
    if @comment.save
      flash[:notice] = "Successfully created comment."
      redirect_to @commentable
    else
      flash[:error] = "Error adding comment."
    end
  end

  private
  def find_commentable
    params.each do |name, value|
      if name =~ /(.+)_id$/
        return $1.classify.constantize.find(value)
      end
    end
    nil
  end

  def comment_params
    params.require(:comment).permit(:body, :parent_id, :commentable_id, :commentable_type)
  end

end

приложение/контроллеры/lessons_controller.rb

class LessonsController < ApplicationController
  include Commentable
...
end

приложение/контроллеры/videos_controller.rb

class VideosController < ApplicationController
  include Commentable
...
end

Модели

приложение/модели/comment.rb

class Comment < ActiveRecord::Base
    has_ancestry
    belongs_to :user
    belongs_to :commentable, polymorphic: true
end

приложение/модели/урок.рб

class Lesson < ActiveRecord::Base
    has_many :comments, :as => :commentable, :dependent => :destroy
end

приложение/модели/видео.рб

class Video < ActiveRecord::Base
    has_many :comments, :as => :commentable, :dependent => :destroy
end

приложение/модели/user.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_many :comments, :as => :commentable, :dependent => :destroy
end

Помощники

приложение/помощники/comments_helper.rb

module CommentsHelper
  def nested_comments(comments)
    comments.map do |comment, sub_comments|
      content_tag(:div, render(comment), :class => "media media-nested")
    end.join.html_safe
  end
end

Либ

/lib/commentable.rb

require 'active_support/concern'

module Commentable
  extend ActiveSupport::Concern

  included do
    before_filter :comments, :only => [:show]
  end

  def comments
    @commentable = find_commentable
    @comments = @commentable.comments.arrange(:order => :created_at)
    @comment = Comment.new
  end

  private

  def find_commentable
    return params[:controller].singularize.classify.constantize.find(params[:id])
  end

end

Схема

create_table "comments", force: true do |t|
    t.text     "body"
    t.integer  "user_id"
    t.integer  "commentable_id"
    t.string   "commentable_type"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "ancestry"
  end

  add_index "comments", ["ancestry"], name: "index_comments_on_ancestry"

Просмотры

Уроки и просмотры show.html.erb

<div class="tab-pane" id="comments">
  <%= nested_comments @comments %>
  <%= render "comments/form" %>
</div>

приложение/просмотры/комментарии/_form.html.erb

<%= form_for [@commentable, @comment] do |f| %>
    <%= f.hidden_field :parent_id %>
    <p>
        <%= f.label :body, "New comment" %>
    </p>
    <%= f.text_area :body, :rows => 4 %>
    <p>
       <%= f.submit "Post Comment" %>
    </p>
<% end %>

приложение/представления/комментарии/_comment.html.erb

<div class="media-body">
  <h4 class="media-heading"><%= comment.user.username %></h4>
  <i>
    <%= comment.created_at.strftime('%b %d, %Y at %H:%M')  %>
  </i>
  <p>
    <%= simple_format comment.body %>
  </p>
  <div class="actions">
    <%= link_to "Reply", new_polymorphic_path([@commentable, Comment.new], :parent_id => comment) %>
  </div>
  <%= nested_comments comment.children %>
</div>

Любые отзывы или идеи будут высоко оценены. Спасибо ;)


person James    schedule 07.12.2014    source источник


Ответы (1)


Выяснил решение, однако теперь дочерние комментарии появляются дважды.

показать.html.erb

<div class="tab-pane" id="comments">
    <%= nested_comments @lesson.comments %>
    <%= render "comments/form" %>
</div>
person James    schedule 20.12.2014