How do I Group Repeatable Fields Programatically? I'm in the middle of coding a custom entity in Drupal 8. Currently, I'm defining fields using the baseFieldDefinitions method. I've run into a small problem now where I have a subset of fields that need to be grouped together and repeatable. For example, I have a checkbox, a text box, and a select box that all need to be associated while allowing someone to click an "Add" button to produce another set of those three fields.

It seems that if I was using the UI to create a custom content type, then I could use Paragraphs to handle this, but I wasn't able to figure out how to do that in code, and all the modules that are used in Drupal 7 as example of how to do this either don't exist in D8, or point to using Paragraphs instead.

Some ideas that I had:


Create all three as repeatable fields in baseFieldDefinitions and override the form to present them as a unit and write some ajax to make it work the way I want. I don't think this is ideal because it seems like I'm fighting the framework.
Make this group of fields into their own entity and try to figure out how to add an entity creation form inside my parent entity creation form. I'm not sure if this is possible, but it seems like it should be.
Use hook_schema to create a database table with the three fields that I need and an additional column to tie that record to my custom entity. This is the way I would have done it in Drupal 7, but I'm worried about the long term of running reports in Views using the data that isn't in the Entity itself. This seems like the quick and dirty way to do it but I don't want a Views headache later.
Figure out how to do this in Paragraphs.


Hopefully, someone with a little more experience than I have in D8 can point me to the most preferable way to handle this. Any help would be greatly appreciated.
I would pick option 3: Create a custom field type that holds all 3 values in one table. This works fine with views. This can be done with Drupal console to simplify the process, see generate:plugin:field. I would also create a separate module for the the plugin with the custom field type so you can test enabling and disabling you main module without running into dependency issues. The advantage of this method over all others is all the data is held in one DB table which keeps things simple and is more efficient.

To briefly touch on your other options, 1 seems dirty and prone to problems. 2 is not bad and does give you more flexibility but means more code and more database tables. If you don't need the added flexibility then there is no need. Paragraphs, Option 4 will create as many DB tables as a custom entity but with less flexibility (you can't add methods to the ContentEntityBase) and more reliance on contrib modules. This is only a good option if your a site builder and don't want to worry about coding.