Self-referencing models
Updated over a week ago

After reading this article, you'll know:

  • What a self-referencing model is

  • How to utilize these models in your application

We created 2 videos about self-referencing models that you might want to check out:

First things first

Before we start, in the use case that'll be used in this article some preparations have been made. A data model called 'Post' is created with the following properties:

  • Title, single-line text;

  • Image, image.

Three pages are already present:

  • Post create, to create new posts;

  • Post overview, a data table that shows all posts;

  • Post details, a detail page for a post, when you click on a post in the overview it'll show the details of that post on this page. We have an example using UUIDs here read it when you're not sure how passing an ID, or UUID to a detail page works.

Before we continue make sure to create a post that a user can view. In this use case we're using a post where we see a picture of a fox:

When we click on the post we get redirected to the detail page:

This will be the starting point from where we'll explain how self-referncing models work. The use case will be that users can comment on this post, and someone can then comment on the comment.

The data model

Go to your data model overview and create a new data model called 'Comment'. We'll add just one property to this model, a text multi-line property with the name 'Message'.

Add a belongs to relation to this model with the 'Post', or vice versa one post has many comments. Now for the 'self-referncing' part, we need to add a relation to this model with itself. One comment belongs to many comments. If everything went well a third relation will automatically be generated resulting in the following relation within the 'Comment' model:

This model is now officially a self-referencing model, it references itself via the relation. Make sure to, for this example, change the permission to public so we can see the comments, same goes for posts if you haven't yet.

Next up is the first functionality, adding a comment on a post.

Adding a comment

Go to the page builder overview, and navigate to the post details page. On this page we'll add the functionality to comment on a post.

Make sure that the data container for the post is on the entire page and that you add the functionality below within that data container otherwise, you won't be able to select the post's data.

Drag a create form underneath the post, add a 'message' property to the create form and make sure to include a hidden input. The hidden input will contain the ID of the post that we want to place a comment on.

Let's go to the action of the create form we just created, for this example make sure that under the settings private action is disabled. The next step is creating a post object that we can assign to a comment, do this in the 'start' step.

The input variable 'ID' is what we'll use, create the action variable like below:

With the 'post_object' in place we can assign it in the create step like this:

Save the action and go back to the page. Let's add the functionality to see the comments on the post. Drag a 'data list' component underneath the create form we just made. Select the 'Comment' model and add the following filter to only show comments from the post that we're viewing the details of:

We can now add a 'text' component on the data list and select the message property of a comment for the post.

To make this user-friendly, add an interaction on the create form to re-fetch the data of the data list we just created. When we create a new comment it'll show up instantly.

Note that the 'create form' is renamed to 'create comment form' and that the 'data list' is renamed to 'primary comment data list'. It's best practice to rename your components so that it's easier to work with them.

With this in place let's check out if it works, hit the 'Play' button in the top-left corner to compile the page and create a new comment. Make sure to change ':id' in the URL with an actual ID of a post, or navigate to the detail page via the post overview page.

And there we go, we can add comments to the post.

Comment on a comment

Now for the self-referencing part, let's see how we can create a comment on one of the comments above. This works almost the same as how we created a comment above.

Drag a 'create form' component underneath the 'text' component that displays the comments message. This will be a bit of an inception with the create form repeating a couple of times but pay attention and it shouldn't be too much of a problem. In the form drag a 'hidden input' component above the multi-text field just like we did previously. Select the ID of the primary comment here:

Now select the create form again for the secondary comment, and navigate to the action of the form.

Create a new action variable like we did before but this time use the 'Comment' model and create a filter as you see in the image above. We can now assign the primary comment to the secondary comment in the 'create' step.

That's how the secondary comment is created. Let's make sure we can also see it shall we? Go back to the details page.

Drag a 'data list' component under the primary comment select 'Comment' as the model and add the following filter so that it only shows secondary comments if the primary comment.

When we create a secondary comment we'd like to see it appear instantly, just like the primary comment don't forget to add an interaction just like before to re-fetch the data of the data list. Hit the 'Play' button in the top-left corner to compile the page and check out if the functionality we just build works. When we fill something in, in the textbox and we click on the button to place the comment we'll see the success alert and our comment underneath the primary comment.

Keep in mind that this page needs a lot of fine-tuning design-wise to make it look any good. Right now it looks very quickly sampled together, which of course it is. Feel free to make it look better and implement this functionality in your own application.

Did this answer your question?