-
Notifications
You must be signed in to change notification settings - Fork 211
/
post_common.rb
93 lines (75 loc) · 2.98 KB
/
post_common.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true
module Thredded
# @abstract Classes that include this module are expected to implement {#readers}.
# @!method readers
# @abstract
# @return [ActiveRecord::Relation<Thredded.user_class>] 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
owners_by_id = result.each_with_object({}) { |r, h| h[r.postable_id] = r.postable }
next result if owners_by_id.empty?
preloader = ActiveRecord::Associations::Preloader.new.preload(
owners_by_id.values, :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
)
preloader[0].preloaded_records.each do |post|
topic = owners_by_id.delete(post.postable_id)
next unless topic
topic.association(:first_post).target = post
end
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