2020-04-18 15:59:18 -07:00
|
|
|
class Answer < ApplicationRecord
|
2020-04-20 14:03:57 -07:00
|
|
|
extend Answer::TimelineMethods
|
|
|
|
|
2024-03-19 14:26:01 -07:00
|
|
|
attr_accessor :has_reacted, :is_subscribed
|
|
|
|
|
2023-02-24 13:59:13 -08:00
|
|
|
belongs_to :user, counter_cache: :answered_count
|
|
|
|
belongs_to :question, counter_cache: :answer_count
|
2014-11-30 10:43:22 -08:00
|
|
|
has_many :comments, dependent: :destroy
|
2023-10-25 20:54:48 -07:00
|
|
|
has_many :smiles, class_name: "Reaction", foreign_key: :parent_id, dependent: :destroy
|
2015-04-20 18:12:11 -07:00
|
|
|
has_many :subscriptions, dependent: :destroy
|
2015-05-04 14:06:57 -07:00
|
|
|
has_many :comment_smiles, through: :comments, source: :smiles
|
2014-12-14 05:34:51 -08:00
|
|
|
|
2023-01-01 12:30:41 -08:00
|
|
|
# rubocop:disable Rails/UniqueValidationWithoutIndex
|
|
|
|
# This cop is disabled here because there already are questions with
|
|
|
|
# multiple answers. Adding an index would break things database-side
|
2023-01-01 12:20:58 -08:00
|
|
|
validates :question_id, uniqueness: { scope: :user_id }
|
2023-01-01 12:30:41 -08:00
|
|
|
# rubocop:enable Rails/UniqueValidationWithoutIndex
|
2023-01-01 12:20:58 -08:00
|
|
|
|
2023-01-28 15:56:47 -08:00
|
|
|
scope :pinned, -> { where.not(pinned_at: nil) }
|
2023-11-26 10:32:50 -08:00
|
|
|
scope :for_user, lambda { |current_user|
|
|
|
|
next select("answers.*", "false as is_subscribed", "false as has_reacted") if current_user.nil?
|
|
|
|
|
|
|
|
select("answers.*",
|
|
|
|
"EXISTS(SELECT 1
|
|
|
|
FROM subscriptions
|
|
|
|
WHERE answer_id = answers.id
|
|
|
|
AND user_id = #{current_user.id}) as is_subscribed",
|
|
|
|
"EXISTS(SELECT 1
|
|
|
|
FROM reactions
|
|
|
|
WHERE parent_id = answers.id
|
|
|
|
AND parent_type = 'Answer'
|
2023-11-27 13:13:56 -08:00
|
|
|
AND user_id = #{current_user.id}) as has_reacted",
|
|
|
|
)
|
2023-11-26 10:32:50 -08:00
|
|
|
}
|
2023-01-28 15:56:47 -08:00
|
|
|
|
2023-01-12 09:23:48 -08:00
|
|
|
SHORT_ANSWER_MAX_LENGTH = 640
|
|
|
|
|
2015-01-03 09:09:56 -08:00
|
|
|
after_create do
|
2024-01-27 04:02:58 -08:00
|
|
|
InboxEntry.where(user: self.user, question: self.question).destroy_all
|
2023-08-16 12:57:31 -07:00
|
|
|
user.touch :inbox_updated_at # rubocop:disable Rails/SkipsModelValidations
|
2015-01-03 10:02:56 -08:00
|
|
|
|
2015-04-22 13:37:50 -07:00
|
|
|
Notification.notify self.question.user, self unless self.question.user == self.user or self.question.user.nil?
|
2015-04-20 18:12:11 -07:00
|
|
|
Subscription.subscribe self.user, self
|
2015-04-22 13:37:50 -07:00
|
|
|
Subscription.subscribe self.question.user, self unless self.question.author_is_anonymous
|
2015-01-03 09:09:56 -08:00
|
|
|
end
|
|
|
|
|
2014-12-28 12:34:42 -08:00
|
|
|
before_destroy do
|
|
|
|
# mark a report as deleted if it exists
|
2015-04-29 17:22:24 -07:00
|
|
|
rep = Report.where(target_id: self.id, type: 'Reports::Answer')
|
2015-04-29 17:04:43 -07:00
|
|
|
rep.each do |r|
|
|
|
|
unless r.nil?
|
|
|
|
r.deleted = true
|
|
|
|
r.save
|
|
|
|
end
|
2014-12-28 12:34:42 -08:00
|
|
|
end
|
2014-12-28 12:20:07 -08:00
|
|
|
|
|
|
|
self.smiles.each do |smile|
|
|
|
|
Notification.denotify self.user, smile
|
|
|
|
end
|
|
|
|
self.comments.each do |comment|
|
2015-04-20 18:12:11 -07:00
|
|
|
Subscription.denotify comment, self
|
2014-12-28 12:20:07 -08:00
|
|
|
end
|
2022-07-17 12:03:23 -07:00
|
|
|
Notification.denotify question&.user, self
|
2015-04-20 18:12:11 -07:00
|
|
|
Subscription.destruct self
|
2014-12-28 12:34:42 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
def notification_type(*_args)
|
2022-07-20 12:43:50 -07:00
|
|
|
Notification::QuestionAnswered
|
2014-12-28 12:20:07 -08:00
|
|
|
end
|
2023-01-12 09:23:48 -08:00
|
|
|
|
|
|
|
def long? = content.length > SHORT_ANSWER_MAX_LENGTH
|
2023-01-28 15:56:47 -08:00
|
|
|
|
|
|
|
def pinned? = pinned_at.present?
|
2024-03-19 14:05:45 -07:00
|
|
|
|
|
|
|
def has_reacted = self.attributes["has_reacted"] || false
|
|
|
|
|
|
|
|
def is_subscribed = self.attributes["is_subscribed"] || false
|
2014-10-27 22:36:38 -07:00
|
|
|
end
|