# frozen_string_literal: true # == Schema Information # # Table name: forums # # id :integer not null, primary key # access_level :string default("normal"), not null # description :string not null # name :string not null # post_access_level :string # post_count :integer default(0), not null # short_name :string not null # topic_count :integer default(0), not null # created_at :datetime not null # updated_at :datetime not null # last_post_id :integer # last_topic_id :integer # # Indexes # # index_forums_on_last_post_id (last_post_id) # index_forums_on_last_topic_id (last_topic_id) # index_forums_on_short_name (short_name) # # Foreign Keys # # fk_rails_... (last_post_id => forum_posts.id) ON DELETE => nullify ON UPDATE => cascade # fk_rails_... (last_topic_id => topics.id) ON DELETE => nullify ON UPDATE => cascade # class Forum < ApplicationRecord belongs_to :last_post, class_name: 'ForumPost', optional: true belongs_to :last_topic, class_name: 'Topic', optional: true has_many :topics has_many :notifications, inverse_of: :actor has_many :subscriptions, dependent: :delete_all has_many :subscribers, through: :subscriptions, source: :user resourcify validates :name, :short_name, uniqueness: true validates :short_name, format: { with: /\A[a-z]+\z/, message: 'must consist only of lowercase letters.' } # Update before destruction before_destroy do |forum| forum.topics.each(&:destroy) # Clear notifications Notification.mark_all_read(forum) Notification.async_cleanup(forum) end def to_param short_name end def refresh_last_post! last_topic = topics.where(hidden_from_users: false).order(last_replied_to_at: :desc).first update_columns(last_topic_id: last_topic&.id, last_post_id: last_topic&.last_post&.id) end def self.get_user_facing_list(user) Forum.order(name: :asc).where(access_level: Forum.access_level_for(user.try(:role))) end def visible_to?(user) Forum.meets_access_level?(user, access_level) end def replyable_to?(user) Forum.meets_access_level?(user, post_access_level) end #noinspection RubyStringKeysInHashInspection ROLE_TO_ACCESS_LEVEL = { 'user' => %w[normal], 'assistant' => %w[normal assistant], 'moderator' => %w[normal assistant staff], 'admin' => %w[normal assistant staff] }.freeze def self.access_level_for(role) ROLE_TO_ACCESS_LEVEL.fetch(role, %w[normal]) end private def self.meets_access_level?(user, level) Forum.access_level_for(user.try(:role)).include?(level) end end