Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter KeystoneJS relationship by id

I'm trying to write a KeystoneJS (Mongoose) model for a Contest collection. These are simplified versions of my actual models:

Contest

Contest.add({
    title: {
      type: Types.Text,
      initial: true,
      required: true,
      index: true
    },

    state: {
      type: Types.Select,
      options: ['draft', 'started', 'finished', 'resolved'],
      default: 'draft'
    },

    awards: {
      idContest: {                        /* <--- copy of _id */
        type: Types.Text,
        hidden: true
      },

      jury: {
        winner: {
          type: Types.Relationship,
          ref: 'Entry',
          many: false,
          filters: {
            'contest.id': ':idContest',   /* <--- filter */
            'contest.state': 'admited'
          }
        }
      }
    }
  });

Entry

Entry.add({
  title: {
    type: Types.Text,
    initial: true,
    required: true,
    index: true
  },

  author: {
    type: Types.Relationship,
    ref: 'User',
    initial: true,
    index: true
  },

  contest: {
    id: {
      type: Types.Relationship,
      ref: 'Contest',
      index: true
    },

    state: {
      type: Types.Select,
      options: ['none', 'review', 'admited', 'rejected'],
      default: 'none',
    }
  }
});

As you can see I'm trying to filter the winner relationship to display only entries that are participating on this contest. But I haven't been able to do it with the contest's id or _id so I just created a new dummy field awards.idContest that is filled with:

Contest.schema.pre('save', function(next) {
   this.awards.idContest = (this.id || this._id);
   next();
});

How could I accomplish the same but without extra fields? Something like:

      jury: {
        winner: {
          type: Types.Relationship,
          ref: 'Entry',
          many: false,
          filters: {
            'contest.id': ':id',
            'contest.state': 'admited'
          }
        }
      }
like image 425
Ignacio Lago Avatar asked Oct 22 '25 08:10

Ignacio Lago


1 Answers

Ignacio, as I mentioned in my comment earlier, as of this writing, Keystone did not provide he ability to filter relationships by the current model's id. However, inspired by your question, I decided to submit a pull request (PR #609) adding this feature to Keystone.

The new feature will work exactly as you expected. In your use case the code would be:

  jury: {
    winner: {
      type: Types.Relationship,
      ref: 'Entry',
      many: false,
      filters: {
        'contest.id': ':_id',   /* <--- filter */
        'contest.state': 'admited'
      }
    }
  }

I will post another comment here once the PR is merged. #609 also includes documentation for the relationship filters feature in general so, once merged, the documentation will be included in the Keystone website after the next build.

like image 178
JME Avatar answered Oct 23 '25 22:10

JME