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]>)


88
89
90
91
92
93
94
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 88

def calculate_post_counts
  states = arel_table
  posts = post_class.arel_table
  relation = joins(states.join(posts).on(states[:postable_id].eq(posts[:postable_id])).join_sources)
    .group(states[:id])
  relation.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.



74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 74

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(true).then(1).else(0)]
    ).as('unread_posts_count'),
    Arel::Nodes::Sum.new(
      [Arel::Nodes::Case.new(posts[:created_at].gt(read_at))
         .when(true).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.



62
63
64
65
66
67
68
69
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 62

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.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/models/concerns/thredded/user_topic_read_state_common.rb', line 41

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(true).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