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