M
M
Melodic2017-05-10 16:17:20
PHP
Melodic, 2017-05-10 16:17:20

How to design an activity feed?

Hello!
There is a website, a social network.
The site has personal user records (personal blog posts), comments, photo albums.
Doctrine is used for database storage.
You need to design an activity feed.
Now it's done like this: when creating something (a comment on a photo, a comment on a user post, photos, user posts), an entity is created (AlbumImageCommentActivity, ArticleCommentActivity, AlbumImageActivity,ArticleActivity, respectively, inherited from the base Activity). Everything would be fine, but when displaying on the page, privacy interferes (and comments don’t have it at all) and at the stage of sampling from the database, I can’t weed out those activities that are not available to the user. Now I’m filtering out after the selection (I just remove it from the array if it didn’t pass the accessibility check), there is a minus here that pagination breaks (each page can have a different number of elements, or even not be at all), but the benefit of the tape is loading, as in VK.
Perhaps initially I went the wrong way.
Your suggestions? :)
And in general, how is the output of entities of different classes in one list?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladislav Ivasik, 2017-07-17
@iqw

I would do the following: I would make an event system, for example - a page was created, a comment was added, and when one of these events occurs, the event is triggered, the handler catches it, writes the main data to a separate table (something like EventLog), fields, which this table contains - user_id(int), date(datetime), event_type(tinyint), triggered_on(int), where user_id is the user's id, binding it directly to the entity, date is the date of the event, event_type is the event type constant (you can describe constants or in another convenient way, I would, for example, make a discriminator by the event_type field with sub-entities, each of which will have a binding to its expected entity type, inheriting getters, there is a lot of space for improving interaction), triggered_on - record id in database that was created-updated etc.After that, we have a list of everything that the user did, the table is quite simple, logging can be expanded.
This stage introduces some kind of denormalization of the data to make it easier to find them.
The second stage is sampling. A simple query is built here, which excludes data that this user does not need.
The user entity is loaded by the join, the rest of the data can be obtained at the time of rendering this list (if there is a discriminator proposed above by requesting something like {{ eventLog.triggeredOn.title }}).
Example - we select all the data in some spectrum (pagination) with an innerjoin to the table of user subscriptions to another user, it turns out that the events of users to which the current user is not subscribed do not fall into the selection already at the level of the request itself, which allows pagination normally without driving into the memory of a huge amount of data.
This mechanism can be sharpened for many variations, if you need more performance - here you need to think in the direction of a competent distribution of data, for example, send them to some kind of elasticsearch, but then queries become more complicated.
In any case, building an effective business logic depends on all the nuances of the task, the final result is up to you, no one will solve such tasks in response to a question on the Question-Answer website :)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question