From 05705f3174e41b1ec913db6cc7f6eb9f7ef60bff Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sat, 18 Jul 2015 17:38:33 +0200 Subject: [PATCH 1/3] configures act_as_commentable_with_threading gem [#7] --- Gemfile | 2 +- Gemfile.lock | 7 +++++++ app/models/comment.rb | 19 +++++++++++++++++ app/models/debate.rb | 2 ++ ...as_commentable_with_threading_migration.rb | 21 +++++++++++++++++++ db/schema.rb | 19 ++++++++++++++++- 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 app/models/comment.rb create mode 100644 db/migrate/20150718091702_acts_as_commentable_with_threading_migration.rb diff --git a/Gemfile b/Gemfile index 45f16f7b4..d393a76b3 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 01408b9c2..f9cb656a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,7 +36,13 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + acts_as_commentable_with_threading (2.0.0) + activerecord (>= 4.0) + activesupport (>= 4.0) + awesome_nested_set (>= 3.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) @@ -188,6 +194,7 @@ PLATFORMS ruby DEPENDENCIES + acts_as_commentable_with_threading byebug capybara coffee-rails (~> 4.1.0) 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 c66913c59..5a11c02cb 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -1,4 +1,6 @@ class Debate < ActiveRecord::Base + acts_as_commentable + validates :title, presence: true validates :description, presence: true 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 61fb86a58..56966e1dc 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: 20150716174358) 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" From 98463e49309bc6eebe12471073fabaa5bf5fd9d0 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sat, 18 Jul 2015 17:38:57 +0200 Subject: [PATCH 2/3] adds comments to debates [#7] --- app/controllers/comments_controller.rb | 28 ++++++++++++++++++++++++++ app/views/comments/_comment.html.erb | 13 ++++++++++++ app/views/comments/_form.html.erb | 7 +++++++ app/views/debates/show.html.erb | 9 +++++++++ config/routes.rb | 4 +++- 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 app/controllers/comments_controller.rb create mode 100644 app/views/comments/_comment.html.erb create mode 100644 app/views/comments/_form.html.erb 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/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 @@ +
+

<%= comment.user.name %>

+

hace <%= time_ago_in_words(comment.created_at) %>

+

<%= comment.body %>

+ +
+ <%= render comment.children %> +
+ +
+ <%= render 'comments/form', parent: comment %> +
+
\ 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 777b22d1b..770be127a 100644 --- a/app/views/debates/show.html.erb +++ b/app/views/debates/show.html.erb @@ -4,5 +4,14 @@

Creado el: <%= l @debate.created_at.to_date %>

+Deja tu comentario +<%= render 'comments/form', parent: @debate %> + +
+

Comentarios

+ <%= render @debate.root_comments %> +
+ +

<%= 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 eae8764ed..cc2da6b4c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,7 +5,9 @@ Rails.application.routes.draw do # You can have the root of your site routed with "root" root 'welcome#index' - resources :debates + resources :debates do + resources :comments, only: :create + end # Example of regular route: # get 'products/:id' => 'catalog#view' From b7086bad4a1b47e905e3337d039b41a4eabdd84a Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sat, 18 Jul 2015 17:39:12 +0200 Subject: [PATCH 3/3] adds comments feature specs [#7] --- spec/factories.rb | 11 +++++ spec/features/comments_spec.rb | 73 ++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 spec/features/comments_spec.rb diff --git a/spec/factories.rb b/spec/factories.rb index 58f320ea7..ca031705d 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -4,4 +4,15 @@ FactoryGirl.define do description 'Debate description' terms_of_service '1' end + + 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