Skip to content

Instantly share code, notes, and snippets.

@raysrashmi
Last active August 29, 2015 14:01
Show Gist options
  • Save raysrashmi/69cf0eaebb2603325077 to your computer and use it in GitHub Desktop.
Save raysrashmi/69cf0eaebb2603325077 to your computer and use it in GitHub Desktop.
class Comment < ActiveRecord::Base
include Attachable, AdminPanel,
Subscribable, Activitable
belongs_to :commentable, polymorphic: true
belongs_to :creator, class_name: User
validates :content, presence: true
validates :commentable, presence: true
validates :creator, presence: true
def project_id
commentable.project_id
end
private
concerning :CommentSearch do
included do
include Tire::Model::Search
include Tire::Model::Callbacks
mapping do
indexes :content
indexes :project_id, type: :integer
indexes :created_at
end
def self.search(term, project_ids)
tire.search(load: true) do
query { string term }
filter :terms, project_id: project_ids
sort { by :created_at, :desc }
end
end
end
def to_indexed_json
to_json(methods: [:project_id])
end
end
end
class CommentCreator
attr_accessor :comment
def initialize(project, creator, params, attachments = [])
@comment = CommentBuilder.new(project, creator, params, attachments).build
end
def create
if comment.save
CommentNotification.new(comment).run
true
else
false
end
end
private
class CommentBuilder
include Subscribers
COMMETABLE = ['Topic', 'Task']
def initialize(project, creator, params, attachments)
@subscribers_ids = params.delete(:subscribers) || []
@creator = creator
@project = project
@attachments = attachments
@params = params
end
def build
comment = new_comment
comment.creator = creator
comment.subscribers = extract_subscribers
comment.attachments = attachments
comment
end
private
attr_reader :project, :creator,
:attachments, :params, :subscribers_ids
def new_comment
Comment.new(params.merge!(commentable: commentable))
end
def commentable
if project.respond_to?(commentable_type)
project.send(commentable_type).
find_by_id(commentable_id)
end
end
def commentable_id
params[:commentable_id]
end
def commentable_type
type = params[:commentable_type]
COMMETABLE.include?(type) ? type.downcase.pluralize : ''
end
end
end
class CommentsController < BaseController
include AttachmentsConcern, Comments
def create
if comment_creator.create
@comment = comment_creator.comment
else
render 'shared/error.coffee'
end
end
def update
authorize_access(@comment)
@comment.attachments = build_attachments_from_tokens
if @comment.update_attributes(comment_params)
ActivityNotifier.new(@comment, current_user,
@comment.commentable.project,
I18n.t('activity.comment_update', subject: @comment.commentable.subject)).run
flash[:notice] = 'Comment updated.'
end
end
private
def comment_params
params.require(:comment).permit(*allowed_params)
end
def attachments_tokens
params[:attachments]
end
end
class Message < ActiveRecord::Base
include Commentable, Attachable, Subscribable,
AdminPanel, Activitable
belongs_to :project
belongs_to :creator, class_name: User
validates :subject, presence: true
validates :creator, presence: true
validates :project, presence: true
validates :type, presence: true
private
concerning :MessageSearch do
included do
include Tire::Model::Search
include Tire::Model::Callbacks
mapping do
indexes :subject
indexes :body
indexes :project_id, type: :integer
indexes :created_at
end
def self.search(term, project_ids)
tire.search(load: true) do
query { string term }
filter :terms, project_id: project_ids
sort { by :created_at, :desc }
end
end
end
end
end
require 'spec_helper'
feature 'message with comment' do
include AccountHelpers, AttachmentHelpers
before do
sign_in
expect_to_have_project
end
scenario 'can post comment with file attachment', :js do
message = create(:message, project: @project)
visit account_project_message_path(@account, @project, message)
expect(message.comments.count).to eq(0)
expect(page).to have_content(message.subject)
expect(page).to have_content(message.body)
expect(page).to have_selector("#comment_content")
fill_in_t 'simple_form.labels.comment.content', with: 'awesome'
upload_files
click_button('Create Comment')
comment = Comment.last
expect(message.comments.count).to eq(1)
expect(comment.attachments.count).to eq(1)
expect(page).to have_content(comment.content)
end
scenario 'able to comment on message without attachment' do
message = create(:message, project: @project)
comment = create(:comment, commentable: message)
visit account_project_message_path(@account, @project, message)
expect(page).to have_content(comment.content)
expect(message.comments.count).to eq(1)
fill_in_t 'simple_form.labels.comment.content', with: 'new comment'
click_button('Create Comment')
message.reload
comment = Comment.last
expect(message.comments.count).to eq(2)
expect(page).to have_content('new comment')
activity = Activity.first
expect(Activity.count).to eq(1)
expect(activity.activitable).to eq(comment)
expect(activity.meta).to eq("commented on #{message.subject}")
expect(activity.url).to eq("#{account_project_message_url(@account, @project, message)}#comment-#{comment.id}")
end
scenario 'not able to comment on message' do
message = create(:message, project: @project)
visit account_project_message_path(@account, @project, message)
fill_in_t 'simple_form.labels.comment.content', with: ''
click_button('Create Comment')
expect(message.comments.count).to eq(0)
end
scenario 'not able to comment if commentable is wrong', :js do
message = create(:message, project: @project)
visit account_project_message_path(@account, @project, message)
fill_in_t 'simple_form.labels.comment.content', with: 'new comment'
find("#comment_commentable_type", :visible => false).set 'Test'
click_button('Create Comment')
expect(message.comments.count).to eq(0)
end
scenario 'not able to comment if commentable id is wrong', :js do
message = create(:message, project: @project)
visit account_project_message_path(@account, @project, message)
fill_in_t 'simple_form.labels.comment.content', with: 'new comment'
find("#comment_commentable_id", :visible => false).set '110'
click_button('Create Comment')
expect(message.comments.count).to eq(0)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment