Smart Field Filtering on Related Data

Hi All -

The documentation shows how to implement filter logic on a smart field:

https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields#filtering

Is it possible to return filter conditions in the Smart Field definition that act on a related model’s data? The example only shows how to filter on the model’s own fields. (this is re: MySQL / Sequelize)

Thanks!

Hello @yeti182 :slight_smile:

Basically I would say yes. Since you’re doing the code you want, you should be able to get any model and put your own logic.

What are you trying to achieve, can you give me more insights?

Great!

Sure thing. Lets say we have a model Books that is related to Checkout Records. There’s a Forest Admin Smart Field (enum type) on Books called status that is one of “In-Hand,” “Checked Out,” or “Lost.”

If I wanted to write the filter logic for showing only “Lost” books, for example, I would need to write the filter logic on the status Smart Field that looks for Books with Checkout Records that have a return_date of greater than a year ago.

Does that make sense? Thanks for your help!

To sum up a little bit you want to be able to filter on a book's smart field called status which will look at book’s related data called checkoutRecords and depends on the return_date data show the book’s records filling these conditions? :slight_smile:

A perfect summary - that’s correct!

Hello @yeti182,

Please find below an example of how you can interact with other collections in filter field

    async filter({ condition, where }) {
      const genres = await models.genres.findAll({
        attributes: ['id'],
        where: {
          name: condition.value,
        },
        include: [{
          model: models.songs,
          attributes: ['id'],
        }],
      });

      let idsToReturn = genres.length ? genres[0].songs.map(song => song.id) : [];
      for (let index = 1; index < genres.length; index += 1) {
        const songIdsForCurrentGenre = genres[index].songs.map(song => song.id);
        idsToReturn = idsToReturn.filter(songId => songIdsForCurrentGenre.includes(songId));
      }

      return {
        id: idsToReturn,
      };
    },

You will need to add some logic to handle different operators you want to supports as described in the documentation

Hope it helps

2 Likes

Thanks, @olesyak - this is very helpful. I think it would be great to show in the documentation that it’s possible to return an array of IDs in a filter function for a SmartField!

I’ll let the team know about your suggestion, thank you!