As far as possible I think the code is clearer if we use CRUD actions rather than custom actions. This will make it easier to add the action to remove votes in the next commit. Note that we are adding this line as we need to validate it that a vote can be created on a comment by the current user: ```authorize! :create, Vote.new(voter: current_user, votable: @comment)``` We have done it this way and not with the following code as you might expect, as this way two votes are created instead of one. ```load_and_authorize_resource through: :comment, through_association: :votes_for``` This line tries to load the resource @comment and through the association "votes_for" it tries to create a new vote associated to that debate. Therefore a vote is created when trying to authorise the resource and then another one in the create action, when calling @comment.vote.
121 lines
3.5 KiB
Ruby
121 lines
3.5 KiB
Ruby
class CommentsController < ApplicationController
|
|
before_action :authenticate_user!, only: [:create, :hide]
|
|
before_action :load_commentable, only: :create
|
|
before_action :verify_resident_for_commentable!, only: :create
|
|
before_action :verify_comments_open!, only: [:create]
|
|
before_action :build_comment, only: :create
|
|
|
|
load_and_authorize_resource
|
|
respond_to :html, :js
|
|
|
|
def create
|
|
if @comment.save
|
|
CommentNotifier.new(comment: @comment).process
|
|
add_notification @comment
|
|
EvaluationCommentNotifier.new(comment: @comment).process if send_evaluation_notification?
|
|
else
|
|
render :new
|
|
end
|
|
end
|
|
|
|
def show
|
|
@comment = Comment.find(params[:id])
|
|
if @comment.valuation && @comment.author != current_user
|
|
raise ActiveRecord::RecordNotFound
|
|
else
|
|
set_comment_flags(@comment.subtree)
|
|
end
|
|
end
|
|
|
|
def flag
|
|
Flag.flag(current_user, @comment)
|
|
set_comment_flags(@comment)
|
|
|
|
render "shared/_refresh_flag_actions", locals: { flaggable: @comment, divider: true }
|
|
end
|
|
|
|
def unflag
|
|
Flag.unflag(current_user, @comment)
|
|
set_comment_flags(@comment)
|
|
|
|
render "shared/_refresh_flag_actions", locals: { flaggable: @comment, divider: true }
|
|
end
|
|
|
|
def hide
|
|
@comment.hide
|
|
set_comment_flags(@comment.subtree)
|
|
end
|
|
|
|
private
|
|
|
|
def comment_params
|
|
params.require(:comment).permit(allowed_params)
|
|
end
|
|
|
|
def allowed_params
|
|
[
|
|
:commentable_type, :commentable_id, :parent_id,
|
|
:body, :as_moderator, :as_administrator, :valuation
|
|
]
|
|
end
|
|
|
|
def build_comment
|
|
@comment = Comment.build(@commentable, current_user, comment_params[:body],
|
|
comment_params[:parent_id].presence,
|
|
comment_params[:valuation])
|
|
check_for_special_comments
|
|
end
|
|
|
|
def check_for_special_comments
|
|
if administrator_comment?
|
|
@comment.administrator_id = current_user.administrator.id
|
|
elsif moderator_comment?
|
|
@comment.moderator_id = current_user.moderator.id
|
|
end
|
|
end
|
|
|
|
def load_commentable
|
|
@commentable = Comment.find_commentable(comment_params[:commentable_type],
|
|
comment_params[:commentable_id])
|
|
end
|
|
|
|
def administrator_comment?
|
|
["1", true].include?(comment_params[:as_administrator]) &&
|
|
can?(:comment_as_administrator, @commentable)
|
|
end
|
|
|
|
def moderator_comment?
|
|
["1", true].include?(comment_params[:as_moderator]) &&
|
|
can?(:comment_as_moderator, @commentable)
|
|
end
|
|
|
|
def add_notification(comment)
|
|
notifiable = comment.reply? ? comment.parent : comment.commentable
|
|
notifiable_author_id = notifiable&.author_id
|
|
if notifiable_author_id.present? && notifiable_author_id != comment.author_id
|
|
Notification.add(notifiable.author, notifiable)
|
|
end
|
|
end
|
|
|
|
def verify_resident_for_commentable!
|
|
return if current_user.administrator? || current_user.moderator?
|
|
|
|
if @commentable.respond_to?(:comments_for_verified_residents_only?) &&
|
|
@commentable.comments_for_verified_residents_only?
|
|
verify_resident!
|
|
end
|
|
end
|
|
|
|
def verify_comments_open!
|
|
return if current_user.administrator? || current_user.moderator?
|
|
|
|
if @commentable.respond_to?(:comments_closed?) && @commentable.comments_closed?
|
|
redirect_to polymorphic_path(@commentable), alert: t("comments.comments_closed")
|
|
end
|
|
end
|
|
|
|
def send_evaluation_notification?
|
|
@comment.valuation && Setting["feature.valuation_comment_notification"]
|
|
end
|
|
end
|