* Ensuring we don't track views of author or unpublished Prior to this commit, I was surprised to learn that we: 1) Tracked an author's view of their article. 2) Tracked views of an unpublished article. This came up from a Forem creator asking if they could reset the view counter. Or trigger the reset on publication. I think a general business logic policy of don't track views for the author and don't track views for unpublished articles is a reasonable default. Were we to pursue the clear views on publication, we'd need to consider something that went from unpublished -> published -> unpublished -> published. Without a more explicit state machine, triggering a busineiss logic behavior seems a bit unexpected. In other words, I wrote an article. There are 20 views when I realize that I need to unpublished it. I make the changes in the unpublished state, and re-publish. I'd assume that those 20 views would still be "recorded" and counted towards my article's view counts. * Adjusting condition structure Prior to this commit, the `if` clause was rather far to the right. This helps make the if clause more pronounced.
33 lines
1.3 KiB
Ruby
33 lines
1.3 KiB
Ruby
module Articles
|
|
# This module is responsible for updating a specific page view for a given article and user.
|
|
#
|
|
# @see Articles::UpdatePageViewsWorker for the sibling that's responsible for recording page
|
|
# views.
|
|
module PageViewUpdater
|
|
# @param article_id [Integer]
|
|
# @param user_id [Integer]
|
|
#
|
|
# @return [TrueClass] if we updated or created a PageView
|
|
# @return [FalseClass] if we did not update a PageView
|
|
#
|
|
# @note Regardless of return status, consider the business logic successful unless we raise an
|
|
# exception. The return value is present for easing testing. The `find_or_create_by`
|
|
# adds a complication in the testing logic
|
|
# (e.g., `expect { Articles::PageViewUpdater.call }.not_to change(PageView, :count) `
|
|
def self.call(article_id:, user_id:)
|
|
# Don't record views to unpublished articles.
|
|
return false if Article.unpublished.exists?(id: article_id)
|
|
# Don't record author's own views.
|
|
return false if Article.published.exists?(id: article_id, user_id: user_id)
|
|
|
|
page_view = PageView.order(created_at: :desc)
|
|
.find_or_create_by(article_id: article_id, user_id: user_id)
|
|
|
|
return true if page_view.new_record?
|
|
|
|
page_view.update_column(:time_tracked_in_seconds, page_view.time_tracked_in_seconds + 15)
|
|
|
|
true
|
|
end
|
|
end
|
|
end
|