Class: BaseBookmarkable
- Inherits:
-
Object
- Object
- BaseBookmarkable
- Defined in:
- app/services/base_bookmarkable.rb
Overview
Anything that we want to be able to bookmark must be registered as a bookmarkable type using Plugin::Instance#register_bookmarkable(bookmarkable_klass), where the bookmarkable_klass is a class that implements this BaseBookmarkable interface. Some examples are TopicBookmarkable and PostBookmarkable.
These methods are then called by the RegisteredBookmarkable class through a public interface, used in places where we need to list, send reminders for, or otherwise interact with bookmarks in a way that is unique to the bookmarkable type.
See RegisteredBookmarkable for additional documentation.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#preload_associations ⇒ Object
readonly
Returns the value of attribute preload_associations.
-
#serializer ⇒ Object
readonly
Returns the value of attribute serializer.
Class Method Summary collapse
-
.after_create(guardian, bookmark, opts) ⇒ Object
Optional additional actions may need to occur after a bookmark is created via the BookmarkManager.
-
.after_destroy(guardian, bookmark, opts) ⇒ Object
Optional additional actions may need to occur after a bookmark is destroyed via the BookmarkManager.
-
.bookmark_metadata(bookmark, user) ⇒ Hash
Some additional information about the bookmark or the surrounding relations may be required when the bookmark is created or destroyed.
-
.can_see?(guardian, bookmark) ⇒ Boolean
Access control is dependent on what has been bookmarked, the appropriate guardian can_see_X? method should be called from the bookmarkable class to determine whether the bookmarkable record (e.g. Post, Topic) is accessible by the guardian user.
-
.can_see_bookmarkable?(guardian, bookmarkable) ⇒ Boolean
The can_see? method calls this one directly.
-
.cleanup_deleted ⇒ Object
Some bookmarkable records are Trashable, and as such we don’t delete the bookmark with dependent_destroy.
- .has_preloads? ⇒ Boolean
-
.list_query(user, guardian) ⇒ Bookmark::ActiveRecord_AssociationRelation
This is where the main query to filter the bookmarks by the provided bookmarkable type should occur.
-
.model ⇒ ActiveRecord::Base
The ActiveRecord model class which will be used to denote the type of the bookmarkable upon registration along with querying.
-
.perform_custom_preload!(bookmarks_of_type, guardian) ⇒ Object
Implementations can define their own preloading logic here.
-
.preload_associations ⇒ Array
Used for preloading associations on the bookmarks for listing purposes.
-
.reminder_conditions(bookmark) ⇒ Boolean
When sending bookmark reminders, we want to make sure that whatever we are sending the reminder for has not been deleted or is otherwise inaccessible.
-
.reminder_handler(bookmark) ⇒ void
Different bookmarkables may have different ways of notifying a user or presenting the reminder and what it is for, so it is up to the bookmarkable to register its preferred method of sending the reminder.
-
.search_query(bookmarks, query, ts_query, &bookmarkable_search) ⇒ Bookmark::ActiveRecord_AssociationRelation
Called from BookmarkQuery when the initial results have been returned by perform_list_query.
-
.send_reminder_notification(bookmark, notification_data) ⇒ void
Can be used by the inheriting class via reminder_handler, most of the time we just want to make a Notification for a bookmark reminder, this gives consumers a way to do it without having provide all of the required data themselves.
-
.serializer ⇒ ApplicationSerializer
The serializer class inheriting from UserBookmarkBaseSerializer.
-
.validate_before_create(guardian, bookmarkable) ⇒ Object
Optional bookmarkable specific validations may need to be run before a bookmark is created via the BookmarkManager.
Instance Attribute Details
#model ⇒ Object (readonly)
Returns the value of attribute model.
16 17 18 |
# File 'app/services/base_bookmarkable.rb', line 16 def model @model end |
#preload_associations ⇒ Object (readonly)
Returns the value of attribute preload_associations.
16 17 18 |
# File 'app/services/base_bookmarkable.rb', line 16 def preload_associations @preload_associations end |
#serializer ⇒ Object (readonly)
Returns the value of attribute serializer.
16 17 18 |
# File 'app/services/base_bookmarkable.rb', line 16 def serializer @serializer end |
Class Method Details
.after_create(guardian, bookmark, opts) ⇒ Object
Optional additional actions may need to occur after a bookmark is created via the BookmarkManager.
195 196 197 |
# File 'app/services/base_bookmarkable.rb', line 195 def self.after_create(guardian, bookmark, opts) # noop end |
.after_destroy(guardian, bookmark, opts) ⇒ Object
Optional additional actions may need to occur after a bookmark is destroyed via the BookmarkManager.
206 207 208 |
# File 'app/services/base_bookmarkable.rb', line 206 def self.after_destroy(guardian, bookmark, opts) # noop end |
.bookmark_metadata(bookmark, user) ⇒ Hash
Some additional information about the bookmark or the surrounding relations may be required when the bookmark is created or destroyed. For example, when destroying a bookmark within a topic we need to know whether there are other bookmarks still remaining in the topic.
173 174 175 |
# File 'app/services/base_bookmarkable.rb', line 173 def self.(bookmark, user) {} end |
.can_see?(guardian, bookmark) ⇒ Boolean
Access control is dependent on what has been bookmarked, the appropriate guardian can_see_X? method should be called from the bookmarkable class to determine whether the bookmarkable record (e.g. Post, Topic) is accessible by the guardian user.
148 149 150 |
# File 'app/services/base_bookmarkable.rb', line 148 def self.can_see?(guardian, bookmark) raise NotImplementedError end |
.can_see_bookmarkable?(guardian, bookmarkable) ⇒ Boolean
The can_see? method calls this one directly. can_see_bookmarkable? can be used in cases where you know the bookmarkable based on type but don’t have a bookmark record to check against.
160 161 162 |
# File 'app/services/base_bookmarkable.rb', line 160 def self.can_see_bookmarkable?(guardian, bookmarkable) raise NotImplementedError end |
.cleanup_deleted ⇒ Object
Some bookmarkable records are Trashable, and as such we don’t delete the bookmark with dependent_destroy. This should be used to delete those records after a grace period, defined by the bookmarkable. For example, post bookmarks may be deleted 3 days after the post or topic is deleted.
In the case of bookmarkable records that are not trashable, and where dependent_destroy is not used, this should just delete the bookmarks pointing to the record which no longer exists in the database.
219 220 221 |
# File 'app/services/base_bookmarkable.rb', line 219 def self.cleanup_deleted # noop end |
.has_preloads? ⇒ Boolean
38 39 40 |
# File 'app/services/base_bookmarkable.rb', line 38 def self.has_preloads? preload_associations.present? end |
.list_query(user, guardian) ⇒ Bookmark::ActiveRecord_AssociationRelation
This is where the main query to filter the bookmarks by the provided bookmarkable type should occur. This should join on additional tables that are required later on to preload additional data for serializers, and also is the place where the bookmarks should be filtered based on security checks, which is why the Guardian instance is provided.
61 62 63 |
# File 'app/services/base_bookmarkable.rb', line 61 def self.list_query(user, guardian) raise NotImplementedError end |
.model ⇒ ActiveRecord::Base
Returns The ActiveRecord model class which will be used to denote the type of the bookmarkable upon registration along with querying.
21 22 23 |
# File 'app/services/base_bookmarkable.rb', line 21 def self.model raise NotImplementedError end |
.perform_custom_preload!(bookmarks_of_type, guardian) ⇒ Object
Implementations can define their own preloading logic here
47 48 49 |
# File 'app/services/base_bookmarkable.rb', line 47 def self.perform_custom_preload!(bookmarks_of_type, guardian) nil end |
.preload_associations ⇒ Array
Returns Used for preloading associations on the bookmarks for listing purposes. Should be in the same format used for .includes() e.g.
- { topic: [:topic_users, :tags
-
}, :user].
34 35 36 |
# File 'app/services/base_bookmarkable.rb', line 34 def self.preload_associations nil end |
.reminder_conditions(bookmark) ⇒ Boolean
When sending bookmark reminders, we want to make sure that whatever we are sending the reminder for has not been deleted or is otherwise inaccessible. Most of the time we can just check if the bookmarkable record is present because it will be trashable, though in some cases there will be additional conditions in the form of a lambda that we should use instead.
The logic around whether it is the right time to send a reminder does not belong here, that is done in the BookmarkReminderNotifications job.
95 96 97 |
# File 'app/services/base_bookmarkable.rb', line 95 def self.reminder_conditions(bookmark) raise NotImplementedError end |
.reminder_handler(bookmark) ⇒ void
This method returns an undefined value.
Different bookmarkables may have different ways of notifying a user or presenting the reminder and what it is for, so it is up to the bookmarkable to register its preferred method of sending the reminder.
106 107 108 |
# File 'app/services/base_bookmarkable.rb', line 106 def self.reminder_handler(bookmark) raise NotImplementedError end |
.search_query(bookmarks, query, ts_query, &bookmarkable_search) ⇒ Bookmark::ActiveRecord_AssociationRelation
Called from BookmarkQuery when the initial results have been returned by perform_list_query. The search_query should join additional tables required to filter the bookmarks further, as well as defining a string used for where_sql, which can include comparisons with the :q parameter.
79 80 81 |
# File 'app/services/base_bookmarkable.rb', line 79 def self.search_query(bookmarks, query, ts_query, &bookmarkable_search) raise NotImplementedError end |
.send_reminder_notification(bookmark, notification_data) ⇒ void
This method returns an undefined value.
Can be used by the inheriting class via reminder_handler, most of the time we just want to make a Notification for a bookmark reminder, this gives consumers a way to do it without having provide all of the required data themselves.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'app/services/base_bookmarkable.rb', line 121 def self.send_reminder_notification(bookmark, notification_data) if notification_data[:data].blank? || notification_data[:data][:bookmarkable_url].blank? || notification_data[:data][:title].blank? raise Discourse::InvalidParameters.new( "A `data` key must be present with at least `bookmarkable_url` and `title` entries.", ) end notification_data[:data] = notification_data[:data].merge( display_username: bookmark.user.username, bookmark_name: bookmark.name, bookmark_id: bookmark.id, bookmarkable_type: bookmark.bookmarkable_type, bookmarkable_id: bookmark.bookmarkable_id, ).to_json notification_data[:notification_type] = Notification.types[:bookmark_reminder] bookmark.user.notifications.create!(notification_data) end |
.serializer ⇒ ApplicationSerializer
Returns The serializer class inheriting from UserBookmarkBaseSerializer.
26 27 28 |
# File 'app/services/base_bookmarkable.rb', line 26 def self.serializer raise NotImplementedError end |
.validate_before_create(guardian, bookmarkable) ⇒ Object
Optional bookmarkable specific validations may need to be run before a bookmark is created via the BookmarkManager. From here an error should be raised if there is an issue with the bookmarkable.
184 185 186 |
# File 'app/services/base_bookmarkable.rb', line 184 def self.validate_before_create(guardian, bookmarkable) # noop end |