-
Notifications
You must be signed in to change notification settings - Fork 0
Notification
The notifications system consists of the Notification
base class and specific classes for each type of notification,
such as the LendRequestNotification
.
To accomplish a kind of inheritance, rails has built-in support for Single Table Inheritance (STI):
All data of subclasses is stored inside a single large table. All columns that aren't needed
for one specific instance are simply filled with NULL
.
Instead of STI, Multiple Table Inheritance (MTI) can be used: Each subclass has its own table for storing custom data. There is one additional table for the base class, which contains information necessary to link to the table of the concrete subclass.
To reduce column bloat, the current design uses MTI over STI. As rails doesn't have built-in support for MTI, an external gem has to be used. It adds the concept of one model acting as another model.
The base model, in our case Notification
, is labeled as being actable
.
Conceptual submodels, e. g. LendRequestNotification
, are labeled as acting_as
the base model.
However, they are not actual subclasses of the base model, but simple models inheriting from ApplicationModel
directly.
Although there is no subclass relationship between the base model and any of the specific models,
one can still treat an instance of a specific model as an instance of the base model and vice versa.
I. e. one can call all methods defined on Notification
on an instance of LendRequestNotification
and one can call all methods defined on LendRequstNotification
on an instance of Notification
,
provided the instance really corresponds to an instance of the specific class.
If needed, instances of the base class and the specific classes can be converted into one another.
The method specific
converts instances of the base model into instances of the specific model
and the method acting_as
does the opposite.
To push a notification to a user, an instance of the specific model has to be created and saved to the database.
To create a notification of type XYZNotification
, which we'll assume has some data named abc
,
and push it to a user john
, do the following:
xyz_notification = XYZNotification.new(user: john, date: Time.now, abc: data)
xyz_notification.save
You can use this template:
class XYZNotification < ApplicationRecord
acts_as :notification
def title
I18n.t "views.notifications.xyz.title"
end
def description
I18n.t "views.notifications.xyz.description"
end
end
Replace the three occurences of xyz
(class name, title and description)
with the name of your notification and don't forget to add the translations.
You can of course have translations depend on the custom data.
Each notification type can display custom markup below the description, like buttons,
with the help of a partial named similarly to the class:
While rendering an instance of SomeInterestingNotification
,
the partial app/views/notifications/_some_interesting_notification.html.erb
will be rendered.
If the partial doesn't exist, no error will be thrown. The partial will be given a notification
parameter containing
the instance of the specific class (SomeInterestingNotification
).