2018-07-25 05:30:33 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-03-28 09:17:42 -04:00
|
|
|
class UserInteractedProject < ApplicationRecord
|
2021-01-27 07:09:01 -05:00
|
|
|
extend SuppressCompositePrimaryKeyWarning
|
|
|
|
|
2018-02-23 14:33:16 -05:00
|
|
|
belongs_to :user
|
|
|
|
belongs_to :project
|
|
|
|
|
2018-03-05 10:50:05 -05:00
|
|
|
validates :project_id, presence: true
|
|
|
|
validates :user_id, presence: true
|
2018-02-23 14:33:16 -05:00
|
|
|
|
2018-02-23 14:56:43 -05:00
|
|
|
CACHE_EXPIRY_TIME = 1.day
|
|
|
|
|
2018-02-26 06:24:02 -05:00
|
|
|
class << self
|
|
|
|
def track(event)
|
|
|
|
# For events without a project, we simply don't care.
|
|
|
|
# An example of this is the creation of a snippet (which
|
|
|
|
# is not related to any project).
|
2018-03-05 10:50:05 -05:00
|
|
|
return unless event.project_id
|
2018-02-26 06:24:02 -05:00
|
|
|
|
|
|
|
attributes = {
|
|
|
|
project_id: event.project_id,
|
|
|
|
user_id: event.author_id
|
|
|
|
}
|
|
|
|
|
2020-09-29 11:10:08 -04:00
|
|
|
cached_exists?(**attributes) do
|
2021-08-18 11:11:07 -04:00
|
|
|
where(attributes).exists? || UserInteractedProject.insert_all([attributes], unique_by: %w(project_id user_id))
|
|
|
|
true
|
2018-02-23 14:56:43 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-26 06:24:02 -05:00
|
|
|
private
|
2018-02-23 14:56:43 -05:00
|
|
|
|
2018-02-26 06:24:02 -05:00
|
|
|
def cached_exists?(project_id:, user_id:, &block)
|
2018-03-01 09:42:04 -05:00
|
|
|
cache_key = "user_interacted_projects:#{project_id}:#{user_id}"
|
2018-02-26 06:24:02 -05:00
|
|
|
Rails.cache.fetch(cache_key, expires_in: CACHE_EXPIRY_TIME, &block)
|
|
|
|
end
|
2018-02-23 14:33:16 -05:00
|
|
|
end
|
|
|
|
end
|