Module: Thredded::UserTopicReadStateCommon::ClassMethods

Defined in:
app/models/concerns/thredded/user_topic_read_state_common.rb

Instance Method Summary collapse

Instance Method Details

#calculate_post_countsArray<[id, unread_posts_count, read_posts_count]>

Returns:

  • (Array<[id, unread_posts_count, read_posts_count]>)


84
85
86
87
88
89
90
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 84

def calculate_post_counts
  states = arel_table
  posts = post_class.arel_table
  joins(states.join(posts).on(states[:postable_id].eq(posts[:postable_id])).join_sources)
    .group(states[:id])
    .pluck(states[:id], *post_counts_arel(states[:read_at], posts: posts))
end

#post_counts_arel(read_at, posts: post_class.arel_table) ⇒ [Arel::Node, Arel::Node]

Returns unread_posts_count and read_posts_count nodes.

Parameters:

  • read_at (DateTime, Arel::Node)
  • posts (Arel::Table) (defaults to: post_class.arel_table)

Returns:

  • ([Arel::Node, Arel::Node])

    unread_posts_count and read_posts_count nodes.



70
71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 70

def post_counts_arel(read_at, posts: post_class.arel_table)
  [
    Arel::Nodes::Sum.new(
      [Arel::Nodes::Case.new(posts[:created_at].gt(read_at))
         .when(Thredded::ArelCompat.true_value(self)).then(1).else(0)]
    ).as('unread_posts_count'),
    Arel::Nodes::Sum.new(
      [Arel::Nodes::Case.new(posts[:created_at].gt(read_at))
         .when(Thredded::ArelCompat.true_value(self)).then(0).else(1)]
    ).as('read_posts_count')
  ]
end

#update_post_counts!Object

Calculates and saves the unread_posts_count and read_posts_count columns.



58
59
60
61
62
63
64
65
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 58

def update_post_counts!
  id_counts = calculate_post_counts_for_users(Thredded.user_class.where(id: distinct.select(:user_id)))
  transaction do
    id_counts.each do |(id, unread_posts_count, read_posts_count)|
      where(id: id).update_all(unread_posts_count: unread_posts_count, read_posts_count: read_posts_count)
    end
  end
end

#with_page_info(posts_per_page: post_class.default_per_page) ⇒ Object

Adds first_unread_post_page and last_read_post_page columns onto the scope. Skips the records that have no read posts.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 37

def with_page_info(posts_per_page: post_class.default_per_page)
  states = arel_table
  selects = []
  selects << states[Arel.star] if !is_a?(ActiveRecord::Relation) || select_values.empty?
  selects += [
    Arel::Nodes::Case.new(states[:unread_posts_count].not_eq(0))
      .when(Thredded::ArelCompat.true_value(self)).then(
        Arel::Nodes::Addition.new(
          Thredded::ArelCompat.integer_division(self, states[:read_posts_count], posts_per_page), 1
        )
      ).else(nil).as('first_unread_post_page'),
    Arel::Nodes::Addition.new(
      Thredded::ArelCompat.integer_division(self, states[:read_posts_count], posts_per_page),
      Arel::Nodes::Case.new(Arel::Nodes::InfixOperation.new(:%, states[:read_posts_count], posts_per_page))
        .when(0).then(0).else(1)
    ).as('last_read_post_page')
  ]
  select(selects)
end