# frozen_string_literal: true module Thredded # @abstract Classes that include this module are expected to implement {#readers}. # @!method readers # @abstract # @return [ActiveRecord::Relation] users from that can read this post. module PostCommon extend ActiveSupport::Concern included do paginates_per Thredded.posts_per_page delegate :email, to: :user, prefix: true, allow_nil: true validates :content, presence: true scope :order_oldest_first, -> { order(created_at: :asc, id: :asc) } scope :order_newest_first, -> { order(created_at: :desc, id: :desc) } scope :preload_first_topic_post, -> { posts_table_name = quoted_table_name result = all ActiveRecord::Associations::Preloader.new.preload( result.map(&:postable), :first_post, unscoped.where(<<~SQL.delete("\n")) #{posts_table_name}.created_at = ( SELECT MAX(p2.created_at) from #{posts_table_name} p2 WHERE p2.postable_id = #{posts_table_name}.postable_id) SQL ) result } before_validation :ensure_user_detail, on: :create after_commit :update_unread_posts_count, on: %i[create destroy] end def avatar_url Thredded.avatar_url.call(user) end def calculate_page(postable_posts, per_page) 1 + postable_posts.where(postable_posts.arel_table[:created_at].lt(created_at)).count / per_page end # @param view_context [Object] the context of the rendering view. # @return [String] formatted and sanitized html-safe post content. def filtered_content(view_context, users_provider: ::Thredded::UsersProvider, **options) Thredded::ContentFormatter.new( view_context, users_provider: users_provider, users_provider_scope: readers, **options ).format_content(content) end def first_post_in_topic? postable.first_post == self end # Marks all the posts from the given one as unread for the given user # @param [Thredded.user_class] user def mark_as_unread(user) if previous_post.nil? read_state = postable.user_read_states.find_by(user_id: user.id) read_state.destroy if read_state else postable.user_read_states.touch!(user.id, previous_post, overwrite_newer: true) end end def previous_post @previous_post ||= postable.posts.order_newest_first.find_by('created_at < ?', created_at) end protected def update_unread_posts_count postable.user_read_states.update_post_counts! end private def ensure_user_detail build_user_detail if user && !user_detail end end end