We were already applying these rules in most cases. Note we aren't enabling the `MultilineArrayLineBreaks` rule because we've got places with many elements whire it isn't clear whether having one element per line would make the code more readable.
161 lines
4.0 KiB
Ruby
161 lines
4.0 KiB
Ruby
class Comment < ApplicationRecord
|
|
include Flaggable
|
|
include HasPublicAuthor
|
|
include Graphqlable
|
|
include Notifiable
|
|
include Searchable
|
|
|
|
COMMENTABLE_TYPES = %w[Debate Proposal Budget::Investment Poll Topic
|
|
Legislation::Question Legislation::Annotation
|
|
Legislation::Proposal].freeze
|
|
|
|
acts_as_paranoid column: :hidden_at
|
|
include ActsAsParanoidAliases
|
|
acts_as_votable
|
|
has_ancestry touch: true
|
|
|
|
attr_accessor :as_moderator, :as_administrator
|
|
|
|
translates :body, touch: true
|
|
include Globalizable
|
|
|
|
validates_translation :body, presence: true
|
|
validates :user, presence: true
|
|
|
|
validates :commentable_type, inclusion: { in: ->(*) { COMMENTABLE_TYPES }}
|
|
|
|
validate :validate_body_length
|
|
validate :comment_valuation, if: -> { valuation }
|
|
|
|
belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true, touch: true
|
|
belongs_to :user, -> { with_hidden }, inverse_of: :comments
|
|
|
|
before_save :calculate_confidence_score
|
|
|
|
scope :for_render, -> { with_hidden.includes(user: :organization) }
|
|
scope :with_visible_author, -> { joins(:user).where(users: { hidden_at: nil }) }
|
|
scope :not_as_admin_or_moderator, -> { where(administrator_id: nil).where(moderator_id: nil) }
|
|
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
|
scope :public_for_api, -> do
|
|
not_valuations
|
|
.where(commentable: [Debate.public_for_api, Proposal.public_for_api, Poll.public_for_api])
|
|
end
|
|
|
|
scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) }
|
|
scope :sort_descendants_by_most_voted, -> { order(confidence_score: :desc, created_at: :asc) }
|
|
scope :sort_by_supports, -> { order(Arel.sql("cached_votes_up - cached_votes_down DESC")) }
|
|
|
|
scope :sort_by_newest, -> { order(created_at: :desc) }
|
|
scope :sort_descendants_by_newest, -> { order(created_at: :desc) }
|
|
|
|
scope :sort_by_oldest, -> { order(created_at: :asc) }
|
|
scope :sort_descendants_by_oldest, -> { order(created_at: :asc) }
|
|
|
|
scope :not_valuations, -> { where(valuation: false) }
|
|
|
|
after_create :call_after_commented
|
|
|
|
def self.build(commentable, user, body, p_id = nil, valuation = false)
|
|
new(commentable: commentable,
|
|
user_id: user.id,
|
|
body: body,
|
|
parent_id: p_id,
|
|
valuation: valuation)
|
|
end
|
|
|
|
def self.find_commentable(c_type, c_id)
|
|
c_type.constantize.find(c_id)
|
|
end
|
|
|
|
def author_id
|
|
user_id
|
|
end
|
|
|
|
def author
|
|
user
|
|
end
|
|
|
|
def author=(author)
|
|
self.user = author
|
|
end
|
|
|
|
def human_name
|
|
body.truncate(32)
|
|
end
|
|
|
|
def total_votes
|
|
cached_votes_total
|
|
end
|
|
|
|
def total_likes
|
|
cached_votes_up
|
|
end
|
|
|
|
def total_dislikes
|
|
cached_votes_down
|
|
end
|
|
|
|
def as_administrator?
|
|
administrator_id.present?
|
|
end
|
|
|
|
def as_moderator?
|
|
moderator_id.present?
|
|
end
|
|
|
|
def after_hide
|
|
commentable_type.constantize.with_hidden.reset_counters(commentable_id, :comments)
|
|
end
|
|
|
|
def after_restore
|
|
commentable_type.constantize.with_hidden.reset_counters(commentable_id, :comments)
|
|
end
|
|
|
|
def reply?
|
|
!root?
|
|
end
|
|
|
|
def call_after_commented
|
|
commentable.after_commented if commentable.respond_to?(:after_commented)
|
|
end
|
|
|
|
def self.body_max_length
|
|
Setting["comments_body_max_length"].to_i
|
|
end
|
|
|
|
def calculate_confidence_score
|
|
self.confidence_score = ScoreCalculator.confidence_score(cached_votes_total,
|
|
cached_votes_up)
|
|
end
|
|
|
|
def votes_score
|
|
cached_votes_up - cached_votes_down
|
|
end
|
|
|
|
def searchable_values
|
|
{
|
|
body => "A",
|
|
commentable&.title => "B"
|
|
}
|
|
end
|
|
|
|
def self.search(terms)
|
|
pg_search(terms)
|
|
end
|
|
|
|
private
|
|
|
|
def validate_body_length
|
|
validator = ActiveModel::Validations::LengthValidator.new(
|
|
attributes: :body,
|
|
maximum: Comment.body_max_length)
|
|
validator.validate(self)
|
|
end
|
|
|
|
def comment_valuation
|
|
unless author.can?(:comment_valuation, commentable)
|
|
errors.add(:valuation, :cannot_comment_valuation)
|
|
end
|
|
end
|
|
end
|