diff --git a/Gemfile b/Gemfile
index 09a70cfe5..da69551ab 100644
--- a/Gemfile
+++ b/Gemfile
@@ -25,7 +25,7 @@ gem 'sdoc', '~> 0.4.0', group: :doc
gem 'devise'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
-
+gem 'acts_as_commentable_with_threading'
# Use Unicorn as the app server
# gem 'unicorn'
diff --git a/Gemfile.lock b/Gemfile.lock
index 9124a06fd..601246774 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -38,8 +38,14 @@ GEM
tzinfo (~> 1.1)
acts-as-taggable-on (3.5.0)
activerecord (>= 3.2, < 5)
+ acts_as_commentable_with_threading (2.0.0)
+ activerecord (>= 4.0)
+ activesupport (>= 4.0)
+ awesome_nested_set (>= 3.0)
acts_as_votable (0.10.0)
arel (6.0.2)
+ awesome_nested_set (3.0.2)
+ activerecord (>= 4.0.0, < 5)
bcrypt (3.1.10)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
@@ -192,6 +198,7 @@ PLATFORMS
DEPENDENCIES
acts-as-taggable-on
+ acts_as_commentable_with_threading
acts_as_votable
byebug
capybara
diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb
new file mode 100644
index 000000000..91a92e5ba
--- /dev/null
+++ b/app/controllers/comments_controller.rb
@@ -0,0 +1,28 @@
+class CommentsController < ApplicationController
+ before_action :authenticate_user!
+ before_action :set_debate, :set_parent
+
+ def create
+ comment = Comment.build(@debate, current_user, params[:comment][:body])
+ comment.save!
+ comment.move_to_child_of(@parent) if reply?
+ redirect_to @debate, notice: "Comentario guardado"
+ end
+
+ private
+ def comment_params
+ params.require(:comments).permit(:commentable_type, :commentable_id, :body)
+ end
+
+ def set_debate
+ @debate = Debate.find(params[:debate_id])
+ end
+
+ def set_parent
+ @parent = Comment.find_parent(params[:comment])
+ end
+
+ def reply?
+ @parent.class == Comment
+ end
+end
\ No newline at end of file
diff --git a/app/models/comment.rb b/app/models/comment.rb
new file mode 100644
index 000000000..3f8dd83f4
--- /dev/null
+++ b/app/models/comment.rb
@@ -0,0 +1,19 @@
+class Comment < ActiveRecord::Base
+ acts_as_nested_set :scope => [:commentable_id, :commentable_type]
+
+ validates :body, :presence => true
+ validates :user, :presence => true
+
+ belongs_to :commentable, :polymorphic => true
+ belongs_to :user
+
+ def self.build(commentable, user, body)
+ new commentable: commentable,
+ user_id: user.id,
+ body: body
+ end
+
+ def self.find_parent(params)
+ params[:commentable_type].constantize.find(params[:commentable_id])
+ end
+end
diff --git a/app/models/debate.rb b/app/models/debate.rb
index 727d805e7..0bebf6b8e 100644
--- a/app/models/debate.rb
+++ b/app/models/debate.rb
@@ -1,8 +1,9 @@
require 'numeric'
class Debate < ActiveRecord::Base
acts_as_votable
+ acts_as_commentable
acts_as_taggable
-
+
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
validates :title, presence: true
diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb
new file mode 100644
index 000000000..a27a689c9
--- /dev/null
+++ b/app/views/comments/_comment.html.erb
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb
new file mode 100644
index 000000000..4ef99b4b0
--- /dev/null
+++ b/app/views/comments/_form.html.erb
@@ -0,0 +1,7 @@
+<%= form_for [@debate, Comment.new] do |f| %>
+ <%= f.text_area :body %>
+ <%= f.hidden_field :commentable_type, value: parent.class %>
+ <%= f.hidden_field :commentable_id, value: parent.id %>
+
+ <%= f.submit 'Publicar comentario' %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb
index 5319939bd..5efdd833a 100644
--- a/app/views/debates/show.html.erb
+++ b/app/views/debates/show.html.erb
@@ -25,7 +25,14 @@
<%= render 'shared/tags', debate: @debate %>
-
- <%= link_to 'Edit', edit_debate_path(@debate) %> |
- <%= link_to 'Back', debates_path %>
-
\ No newline at end of file
+Deja tu comentario
+<%= render 'comments/form', parent: @debate %>
+
+
+
+
+<%= link_to 'Edit', edit_debate_path(@debate) %> |
+<%= link_to 'Back', debates_path %>
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 948beedb8..a527a7ad5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -8,6 +8,7 @@ Rails.application.routes.draw do
root 'welcome#index'
resources :debates do
resources :votes, only: :create
+ resources :comments, only: :create
end
# Example of regular route:
diff --git a/db/migrate/20150718091702_acts_as_commentable_with_threading_migration.rb b/db/migrate/20150718091702_acts_as_commentable_with_threading_migration.rb
new file mode 100644
index 000000000..728b26b9e
--- /dev/null
+++ b/db/migrate/20150718091702_acts_as_commentable_with_threading_migration.rb
@@ -0,0 +1,21 @@
+class ActsAsCommentableWithThreadingMigration < ActiveRecord::Migration
+ def self.up
+ create_table :comments, :force => true do |t|
+ t.integer :commentable_id
+ t.string :commentable_type
+ t.string :title
+ t.text :body
+ t.string :subject
+ t.integer :user_id, :null => false
+ t.integer :parent_id, :lft, :rgt
+ t.timestamps
+ end
+
+ add_index :comments, :user_id
+ add_index :comments, [:commentable_id, :commentable_type]
+ end
+
+ def self.down
+ drop_table :comments
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a9958aba6..1a32c61a7 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,24 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150718075337) do
+ActiveRecord::Schema.define(version: 20150718091702) do
+
+ create_table "comments", force: :cascade do |t|
+ t.integer "commentable_id"
+ t.string "commentable_type"
+ t.string "title"
+ t.text "body"
+ t.string "subject"
+ t.integer "user_id", null: false
+ t.integer "parent_id"
+ t.integer "lft"
+ t.integer "rgt"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type"
+ add_index "comments", ["user_id"], name: "index_comments_on_user_id"
create_table "debates", force: :cascade do |t|
t.string "title"
diff --git a/spec/factories.rb b/spec/factories.rb
index b34315ef0..9a7ce6181 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -18,6 +18,15 @@ FactoryGirl.define do
association :votable, factory: :debate
association :voter, factory: :user
vote_flag true
+
+ factory :comment do
+ commentable
+ user
+ body 'Comment body'
+ end
+
+ factory :commentable do
+ debate
end
end
\ No newline at end of file
diff --git a/spec/features/comments_spec.rb b/spec/features/comments_spec.rb
new file mode 100644
index 000000000..c4b0e163b
--- /dev/null
+++ b/spec/features/comments_spec.rb
@@ -0,0 +1,73 @@
+require 'rails_helper'
+include ActionView::Helpers::DateHelper
+
+feature 'Comments' do
+
+ scenario 'Index' do
+ debate = create(:debate)
+ 3.times { create(:comment, commentable: debate) }
+
+ visit debate_path(debate)
+
+ expect(page).to have_css('.comment', count: 3)
+
+ comment = Comment.first
+ within first('.comment') do
+ expect(page).to have_content comment.user.name
+ expect(page).to have_content time_ago_in_words(comment.created_at)
+ expect(page).to have_content comment.body
+ end
+ end
+
+ scenario 'Create' do
+ user = create(:user)
+ debate = create(:debate)
+
+ login_as(user)
+ visit debate_path(debate)
+
+ fill_in 'comment_body', with: '¿Has pensado en esto...?'
+ click_button 'Publicar comentario'
+
+ expect(page).to have_content 'Comentario guardado'
+
+ within "#comments" do
+ expect(page).to have_content '¿Has pensado en esto...?'
+ end
+ end
+
+ scenario 'Reply' do
+ citizen = create(:user, first_name: 'Ana')
+ manuela = create(:user, first_name: 'Manuela')
+ debate = create(:debate)
+ comment = create(:comment, commentable: debate, user: citizen)
+
+ visit debate_path(debate)
+ login_as(manuela)
+
+ within "#comment-#{comment.id}" do
+ fill_in 'comment_body', with: 'La semana que viene está hecho.'
+ click_button 'Publicar comentario'
+ end
+
+ expect(page).to have_content 'Comentario guardado'
+ within "#comment-#{comment.id}" do
+ expect(page).to have_content 'La semana que viene está hecho.'
+ end
+ end
+
+ scenario "N replies" do
+ debate = create(:debate)
+ parent = create(:comment, commentable: debate)
+
+ 7.times do
+ create(:comment, commentable: debate).
+ move_to_child_of(parent)
+ parent = parent.children.first
+ end
+
+ visit debate_path(debate)
+ expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
+ end
+
+end
\ No newline at end of file
<%= comment.user.name %>
+hace <%= time_ago_in_words(comment.created_at) %>
+<%= comment.body %>
+ +