Open theharshin opened 5 years ago
The repeater with multiple fields will be a relational interface in that case, correct? The way you describe it, making the group repeater a relational interface gives us the ability to rely on directus_fields
for setting up the fields, and it'll take care of saving / retrieving the data, as it's now a "regular" one-to-many in a different visual style
Also, thinking about that, I don't think there have to be 2 interfaces. A repeater with only 1 field is... just that: a repeater with only 1 field setup instead of multiple. It can still follow the same relational setup
When we consider relational, there will be a separate table for the data right? For repeater, there won't be any new table but just an array of data.
So if a single field is repeated, data will be saved like this:
"key":["value_1","value_2"]
For an Interface Group the data should be like this:
"key":{
"child_key_1":"child_value_1",
"child_key_2":"child_value_2"
}
And if the Interface Group is Repeated, the data should be like this:
"key":[{
"child_1_key_1":"child_1_value_1",
"child_1_key_2":"child_1_value_2"
},
{
"child_2_key_1":"child_2_value_1",
"child_2_key_2":"child_2_value_2"
}]
So we need only 1 new interface which is "Interface Group".
For repeater, there won't be any new table but just an array of data.
Why?
Why not go relational?
How are fields / fields-config stored if it's not relational?
The relational may not make sense every time and if you need relational interfaces we already have those. Let me give you some examples.
The Carousel Consider adding a carousel inside a blog article. Each slide has title, description and an image. Making a relational table would be overkill here. Instead we can use Interface Group. Each group will have child interfaces for title, description, image. This would be a quick and straight forward to manage.
Social Links An author bio can have dynamic links. We can create an interface group for icon and a link and make it repeatable.
Both the cases can be achieved via relational setup too. But that we can leave on developers how they want to manage.
The child fields will be an alias, so the directus_fields
will contain all the information but a collection won't have a column of it. directus_fields
contains a column group
where we can define a parent field or we can also add a new key under options
.
Each group will have child interfaces for title, description, image. This would be a quick and straight forward to manage.
This is exactly how the current repeater works. The only problem is where the field options are stored. We need to store all the information that's normally stored in directus_fields
somewhere. It can't be in directus_fields
however, cause these fields aren't fields of any collection. They're "sub-fields" (for lack of a better term) of the one field that is part of the collection.
The only way we can accurately store this information is if the sub-fields are fields of a related collection, and each row here is an item in the related collection (which also makes the most sense from a data storing normalization perspective).
I also don't agree with "Making a relational table would be overkill here.", as that's exactly what we do for One-to-Many fields, which are arguably the exact same setup as this.
The "sub-fields" are same as fields and represented by interfaces, thus the Directus must have full control over it, so making a JSON is not a choice.
Is keeping "sub-fields" inside directus_fields
a very bad thing? Can't we distinguish them with a new column, say parent
which will contain the name of parent field?
The relational approach is undoubtedly the best way to manage data (except the setup 😅) There will be a major difference in setup process for the approaches.
repeater
mode.repeater
interface.I see there was a discussion on multiple types of repeater fields here: https://github.com/directus/app/issues/1205#issuecomment-480884171 Does that relate to what we're discussing here 🤔 @benhaynes
An interesting point... let's see what @rijkvanzanten thinks when he's available.
Can't we distinguish them with a new column, say
parent
which will contain the name of parent field?
This is a common practice on how to store tree-like structures in the same table. Querying makes it a bit harder though. But in can be solved with a recursive CTE.
Using
I agree that there definetly needs to be a relational Version so that every Interface is able to be used.
But i (maybe) see an Issue when thinking about Query-chaining though. Making a JSON Repeater will flatten Querries a lot on bigger sets of data. Though ultimately for normal CMS usage this shouldn't matter. Just throwing this in right now.
Thanks @edenprojectde — those seem to me like two different repeater interfaces... which I think makes sense. We can build these separately so both are clean and organized, similar to checkboxes
and checkboxes-relational
.
It would be a good idea to update the current repeater interface to hide the relational interfaces for that one seeing that it doesn't work with the relational interfaces to begin with. I think we might be able to scan for the o2m / m2o / translation types for each of the interfaces
Is this coming with directus 8 or 9?
Yup! Hard to give an exact release date though.
Thanks for the quick answer! Do you think it's a matter of days/weeks/months?
Hoping to be able to add it in to v9, which is closer to weeks than months, but definitely not days.
Maybe it will be much like Wordpress Custom Fields work. Is a very flexible and fast way to put some data, in a objects database like style.
I think a key point here, and maybe I'm late for this, is to let choose between diferent possible interface groups in each item the user creates. If you take a look over Flexible type in WP Custom Fields is what it does.
It solves the option for a "M2MM" relation type. I think you called it like this, once ago when was announced in directus 6 times. I implemented a hack over directus 6 (while learning backbone? at that time) to achive this. It worked but with a couple of no user-friendly steps.
From strict relational database perspective it's maybe a strange, no so good, thing to do. But for content creation, that has really no need to be more than a document tree of different structs of data it's a pretty good option. Like when making web pages, in many cases.
I think it is currently not avaiable a relational field in a repeater's field types? Or I'm wrong? It will be possible soon?
I don't have quite enough knowledge of how it works now. I will watch it closer to be able to help. But maybe this idea can help:
With all this, I think it is important to see that all that can be thought as only a way to help and constraint the creation of JSON fields. "Nothing more to check". And if current value not matches definition the user can avoid the helper o reset/merge values.
Nested collections would work as standard collections but bypassing the steps implying create/alter/drop/delete/... for a real table in the user space. And are not elegible to query data from the API.
Problems with current repeater interface.
The configuration of child interfaces is saved as JSON in the database. Those fields are not available inside
directus_fields
. This makes those fields isolated from Directus system and prevents future updates being applied at fields level.The repeater child interfaces does not follow Directus' default field creation process, hence the default schema & configurations are not being applied.
Complex UX. The whole field creation process is placed under single accordion, which makes configuration difficult when there are many child fields.
Proposed Changes
Consider
repeater
as an interface option instead of a separate interface.When user selects any interface and turns on the
repeater
option, the Field Type will be always an Array and MySQL Datatype can be changed to TEXTThe app will handle the repeater field like this. (Just like tag interface but with a button and repeated inputs)
How to repeat multiple fields?
Introduce a new interface called Interface Group
Allow adding a child interfaces under Interface Group Just an idea how it would look:
As the repeater is now an option of interface, Interface Group can also be repeated just like single field.
The Field Type will still remain an Array and data saved in DB will be an array. Each item inside an array will be a JSON with child field as key.
Child interface should be treated as an alias field as it does not have an independent values but will be under parent interface.
directus_fields
will contain all the information about child fields. To map the child field to parent field, we can use thegroup
column.(which is already there)There are already few issues with repeater fields which might be solved with proposed changes. directus/app#1994, directus/app#1985, directus/app#1965, directus/app#1903, directus/app#1864, directus/app#1861, directus/app#1845, directus/app#1818 This will be a breaking change.