I have a Symfony 4 application on which users can view sports events and register themselves for these events. I use Doctrine as ORM and EasyAdminBundle for an admin panel.
I'm having difficulty with figuring out how to structure my entities and how things should be stored in the database. I have 2 main entities, Event
and Registration
. I will explain these in detail.
Event
Event
stores all details about an event. There are some fixed properties that all events have, like:
id
title
description
startDate
endDate
(optional)isPublic
eventType
As you can see, each event has a type. Most events are simple and do not contain additional properties. However, there is an event type for which I want to store some additional properties. I'll call this type complexEventType
from here on out. I'll describe what kind of properties I want to keep for these events:
- How many days does the event take (this varies)?
- For each day: what activities can be done one this day. This should be editable by an admin in the admin panel. There are activities like running, biking, walking, but it should be possible to add other sports.
- Each activity has an optional array of generic options (string). Most of the time, these represent distances.
An example complexEventType
could look like this:
- Day 1
- Walking
- 5km
- 8km
- 12km
- Running
- 10km
- 12km
- 16km
- Biking
- 30km
- 40km
- 60km
- Walking
- Day 2
- Walking
- 8km
- 10km
- 12km
- Running
- 12km
- 14km
- 18km
- Biking
- 40km
- 50km
- 70km
- Walking
- Day 3
- Swimming
- Running
- 12km
- 14km
- 18km
- Biking
- 40km
- 50km
- 70km
Some questions arise here:
- Should I subclass the Event instead of keeping a
type
property? - If I subclass, should each event type have a separate table?
- Instead of subclassing, should I keep the
options
property and make it nullable so that it doesn't need to be set for events where there are no options? - How to store the options in the database? As a JSON object? Or separate tables for days and activities?
Registration
Users can register for events. Their registration will be saved in a Registration
object. A registration contains the following properties:
id
event
(reference to the event object)user
(reference to the registered user)
If the isPublic
boolean from the event
is true
, the event is public and non-authenticated users can register for them. In that case, I want to keep some extra information:
firstName
lastName
email
Depending on the eventType
property from the event
, some extra properties need to be saved. For example, one event type takes places in a foreign country. For this event type, I want to know if the user wants to stay in a hotel (boolean) and whether it's ok if he/she sleeps in a shared room (boolean). For another event type, no details are kept. For the complexEventType
, we need to store which activity the user is doing on what days, and the chosen option for each activity (distance).
I'm kind of in the dark about how I should approach this situation. For now, I created an abstract Registration
entity, which is subclassed by PublicRegistration
and PrivateRegistration
. PublicRegistration
keeps properties like firstName
and lastName
, while PrivateRegistration
stores a pointer to the User
object. Right now, Registration
stores all possible options, which are all nullable. This works, but it doesn't look good at all. I'd rather have the options separated. I was thinking to make an RegistrationOptionInterface
. Then, for each event type, I could create a class that implements this interface and adds options. However, I don't know how this would then be saved to the database...
Can anybody point me in the right direction? Has anybody encountered a similar situation before, and if so, how did you solve it?