123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- # frozen_string_literal: true
- # == Schema Information
- #
- # Table name: announcements
- #
- # id :bigint(8) not null, primary key
- # text :text default(""), not null
- # published :boolean default(FALSE), not null
- # all_day :boolean default(FALSE), not null
- # scheduled_at :datetime
- # starts_at :datetime
- # ends_at :datetime
- # created_at :datetime not null
- # updated_at :datetime not null
- # published_at :datetime
- # status_ids :bigint(8) is an Array
- #
- class Announcement < ApplicationRecord
- scope :unpublished, -> { where(published: false) }
- scope :published, -> { where(published: true) }
- scope :chronological, -> { order(coalesced_chronology_timestamps.asc) }
- scope :reverse_chronological, -> { order(coalesced_chronology_timestamps.desc) }
- has_many :announcement_mutes, dependent: :destroy
- has_many :announcement_reactions, dependent: :destroy
- validates :text, presence: true
- validates :starts_at, presence: true, if: :ends_at?
- validates :ends_at, presence: true, if: :starts_at?
- before_validation :set_published, on: :create
- class << self
- def coalesced_chronology_timestamps
- Arel.sql(
- <<~SQL.squish
- COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at)
- SQL
- )
- end
- end
- def to_log_human_identifier
- text
- end
- def publish!
- update!(published: true, published_at: Time.now.utc, scheduled_at: nil)
- end
- def unpublish!
- update!(published: false, scheduled_at: nil)
- end
- def mentions
- @mentions ||= Account.from_text(text)
- end
- def statuses
- @statuses ||= begin
- if status_ids.nil?
- []
- else
- Status.with_includes.distributable_visibility.where(id: status_ids)
- end
- end
- end
- def tags
- @tags ||= Tag.find_or_create_by_names(Extractor.extract_hashtags(text))
- end
- def emojis
- @emojis ||= CustomEmoji.from_text(text)
- end
- def reactions(account = nil)
- grouped_ordered_announcement_reactions.select(
- [:name, :custom_emoji_id, 'COUNT(*) as count'].tap do |values|
- values << value_for_reaction_me_column(account)
- end
- ).to_a.tap do |records|
- ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji).call
- end
- end
- private
- def grouped_ordered_announcement_reactions
- announcement_reactions
- .group(:announcement_id, :name, :custom_emoji_id)
- .order(
- Arel.sql('MIN(created_at)').asc
- )
- end
- def value_for_reaction_me_column(account)
- if account.nil?
- 'FALSE AS me'
- else
- <<~SQL.squish
- EXISTS(
- SELECT 1
- FROM announcement_reactions inner_reactions
- WHERE inner_reactions.account_id = #{account.id}
- AND inner_reactions.announcement_id = announcement_reactions.announcement_id
- AND inner_reactions.name = announcement_reactions.name
- ) AS me
- SQL
- end
- end
- def set_published
- return unless scheduled_at.blank? || scheduled_at.past?
- self.published = true
- self.published_at = Time.now.utc
- end
- end
|