announcement.rb 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: announcements
  5. #
  6. # id :bigint(8) not null, primary key
  7. # text :text default(""), not null
  8. # published :boolean default(FALSE), not null
  9. # all_day :boolean default(FALSE), not null
  10. # scheduled_at :datetime
  11. # starts_at :datetime
  12. # ends_at :datetime
  13. # created_at :datetime not null
  14. # updated_at :datetime not null
  15. # published_at :datetime
  16. # status_ids :bigint(8) is an Array
  17. #
  18. class Announcement < ApplicationRecord
  19. scope :unpublished, -> { where(published: false) }
  20. scope :published, -> { where(published: true) }
  21. scope :without_muted, ->(account) { joins("LEFT OUTER JOIN announcement_mutes ON announcement_mutes.announcement_id = announcements.id AND announcement_mutes.account_id = #{account.id}").where('announcement_mutes.id IS NULL') }
  22. scope :chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) ASC')) }
  23. scope :reverse_chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) DESC')) }
  24. has_many :announcement_mutes, dependent: :destroy
  25. has_many :announcement_reactions, dependent: :destroy
  26. validates :text, presence: true
  27. validates :starts_at, presence: true, if: -> { ends_at.present? }
  28. validates :ends_at, presence: true, if: -> { starts_at.present? }
  29. before_validation :set_published, on: :create
  30. def to_log_human_identifier
  31. text
  32. end
  33. def publish!
  34. update!(published: true, published_at: Time.now.utc, scheduled_at: nil)
  35. end
  36. def unpublish!
  37. update!(published: false, scheduled_at: nil)
  38. end
  39. def time_range?
  40. starts_at.present? && ends_at.present?
  41. end
  42. def mentions
  43. @mentions ||= Account.from_text(text)
  44. end
  45. def statuses
  46. @statuses ||= begin
  47. if status_ids.nil?
  48. []
  49. else
  50. Status.where(id: status_ids, visibility: [:public, :unlisted])
  51. end
  52. end
  53. end
  54. def tags
  55. @tags ||= Tag.find_or_create_by_names(Extractor.extract_hashtags(text))
  56. end
  57. def emojis
  58. @emojis ||= CustomEmoji.from_text(text)
  59. end
  60. def reactions(account = nil)
  61. records = begin
  62. scope = announcement_reactions.group(:announcement_id, :name, :custom_emoji_id).order(Arel.sql('MIN(created_at) ASC'))
  63. if account.nil?
  64. scope.select('name, custom_emoji_id, count(*) as count, false as me')
  65. else
  66. scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{account.id} and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me")
  67. end
  68. end
  69. ActiveRecord::Associations::Preloader.new.preload(records, :custom_emoji)
  70. records
  71. end
  72. private
  73. def set_published
  74. return unless scheduled_at.blank? || scheduled_at.past?
  75. self.published = true
  76. self.published_at = Time.now.utc
  77. end
  78. end