Class: Bookmark

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/bookmark.rb

Constant Summary collapse

DEFAULT_BOOKMARKABLES =
[
  RegisteredBookmarkable.new(PostBookmarkable),
  RegisteredBookmarkable.new(TopicBookmarkable),
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.auto_delete_preferencesObject



31
32
33
34
# File 'app/models/bookmark.rb', line 31

def self.auto_delete_preferences
  @auto_delete_preferences ||=
    Enum.new(never: 0, when_reminder_sent: 1, on_owner_reply: 2, clear_reminder: 3)
end

.cleanup!Object

Deletes bookmarks that are attached to the bookmarkable records that were deleted more than X days ago. We don’t delete bookmarks instantly when trashable bookmarkables are deleted so that there is a grace period to un-delete.



184
185
186
# File 'app/models/bookmark.rb', line 184

def self.cleanup!
  Bookmark.registered_bookmarkables.each(&:cleanup_deleted)
end

.count_per_day(opts = nil) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'app/models/bookmark.rb', line 154

def self.count_per_day(opts = nil)
  opts ||= {}
  result =
    where(
      "bookmarks.created_at >= ?",
      opts[:start_date] || (opts[:since_days_ago] || 30).days.ago,
    )

  result = result.where("bookmarks.created_at <= ?", opts[:end_date]) if opts[:end_date]

  if opts[:category_id]
    result =
      result
        .joins(
          "LEFT JOIN posts ON posts.id = bookmarks.bookmarkable_id AND bookmarks.bookmarkable_type = 'Post'",
        )
        .joins(
          "LEFT JOIN topics ON (topics.id = bookmarks.bookmarkable_id AND bookmarks.bookmarkable_type = 'Topic') OR (topics.id = posts.topic_id)",
        )
        .where("topics.deleted_at IS NULL AND posts.deleted_at IS NULL")
        .merge(Topic.in_category_and_subcategories(opts[:category_id]))
  end

  result.group("date(bookmarks.created_at)").order("date(bookmarks.created_at)").count
end

.registered_bookmarkable_from_type(type) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'app/models/bookmark.rb', line 13

def self.registered_bookmarkable_from_type(type)
  begin
    resolved_type = Bookmark.polymorphic_class_for(type).name
    Bookmark.registered_bookmarkables.find { |bm| bm.model.name == resolved_type }

    # If the class cannot be found from the provided type using polymorphic_class_for,
    # then the type is not valid and thus there will not be any registered bookmarkable.
  rescue NameError
  end
end

.registered_bookmarkablesObject



9
10
11
# File 'app/models/bookmark.rb', line 9

def self.registered_bookmarkables
  Set.new(DEFAULT_BOOKMARKABLES | DiscoursePluginRegistry.bookmarkables)
end

.select_type(bookmarks_relation, type) ⇒ Object



36
37
38
# File 'app/models/bookmark.rb', line 36

def self.select_type(bookmarks_relation, type)
  bookmarks_relation.select { |bm| bm.bookmarkable_type == type }
end

.valid_bookmarkable_typesObject



24
25
26
# File 'app/models/bookmark.rb', line 24

def self.valid_bookmarkable_types
  Bookmark.registered_bookmarkables.map { |bm| bm.model.polymorphic_name }
end

Instance Method Details

#auto_clear_reminder_when_reminder_sent?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'app/models/bookmark.rb', line 114

def auto_clear_reminder_when_reminder_sent?
  self.auto_delete_preference == Bookmark.auto_delete_preferences[:clear_reminder]
end

#auto_delete_when_reminder_sent?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'app/models/bookmark.rb', line 110

def auto_delete_when_reminder_sent?
  self.auto_delete_preference == Bookmark.auto_delete_preferences[:when_reminder_sent]
end

#bookmark_limit_not_reachedObject



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'app/models/bookmark.rb', line 87

def bookmark_limit_not_reached
  return if user.bookmarks.count < SiteSetting.max_bookmarks_per_user
  return if !new_record?

  self.errors.add(
    :base,
    I18n.t(
      "bookmarks.errors.too_many",
      user_bookmarks_url: "#{Discourse.base_url}/my/activity/bookmarks",
      limit: SiteSetting.max_bookmarks_per_user,
    ),
  )
end

#clear_reminder!Object



122
123
124
# File 'app/models/bookmark.rb', line 122

def clear_reminder!
  update!(reminder_last_sent_at: Time.zone.now, reminder_set_at: nil)
end

#ensure_sane_reminder_at_timeObject



77
78
79
80
81
82
83
84
85
# File 'app/models/bookmark.rb', line 77

def ensure_sane_reminder_at_time
  return if reminder_at.blank?
  if reminder_at < Time.zone.now
    self.errors.add(:base, I18n.t("bookmarks.errors.cannot_set_past_reminder"))
  end
  if reminder_at > 10.years.from_now.utc
    self.errors.add(:base, I18n.t("bookmarks.errors.cannot_set_reminder_in_distant_future"))
  end
end

#polymorphic_columns_presentObject



59
60
61
62
63
# File 'app/models/bookmark.rb', line 59

def polymorphic_columns_present
  return if self.bookmarkable_id.present? && self.bookmarkable_type.present?

  self.errors.add(:base, I18n.t("bookmarks.errors.bookmarkable_id_type_required"))
end

#registered_bookmarkableObject



55
56
57
# File 'app/models/bookmark.rb', line 55

def registered_bookmarkable
  Bookmark.registered_bookmarkable_from_type(self.bookmarkable_type)
end

#reminder_at_ics(offset: 0) ⇒ Object



118
119
120
# File 'app/models/bookmark.rb', line 118

def reminder_at_ics(offset: 0)
  (reminder_at + offset).strftime(I18n.t("datetime_formats.formats.calendar_ics"))
end

#reminder_at_in_zone(timezone) ⇒ Object



126
127
128
# File 'app/models/bookmark.rb', line 126

def reminder_at_in_zone(timezone)
  self.reminder_at.in_time_zone(timezone)
end

#unique_per_bookmarkableObject



65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/bookmark.rb', line 65

def unique_per_bookmarkable
  if !Bookmark.exists?(
       user_id: user_id,
       bookmarkable_id: bookmarkable_id,
       bookmarkable_type: bookmarkable_type,
     )
    return
  end

  self.errors.add(:base, I18n.t("bookmarks.errors.already_bookmarked", type: bookmarkable_type))
end

#valid_bookmarkable_typeObject



101
102
103
104
105
106
107
108
# File 'app/models/bookmark.rb', line 101

def valid_bookmarkable_type
  return if Bookmark.valid_bookmarkable_types.include?(self.bookmarkable_type)

  self.errors.add(
    :base,
    I18n.t("bookmarks.errors.invalid_bookmarkable", type: self.bookmarkable_type),
  )
end