4

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'
          }
        }
      }
Ignacio Lago
  • 2,432
  • 1
  • 27
  • 33
  • Can you provide the definition of the `Entry` list to which you refer in the `jury` field? It would be hard to give you a conclusive answer without it. – JME Sep 03 '14 at 10:49
  • @JohnnyEstilles I've added the `Entry` model. Thank you. – Ignacio Lago Sep 03 '14 at 11:21
  • 1
    Ignacio, that is a very interesting use case. Keystone's relationship `filters` options does not currently have the capability to perform such a filter. Later today I will be submitting a PR to add and document the functionality you're looking for. I will post an answer here as soon as the PR gets merged. – JME Sep 03 '14 at 17:39

1 Answers1

5

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.

JME
  • 3,592
  • 17
  • 24
  • [PR #609](https://github.com/keystonejs/keystone/pull/609) was merged today. The functionality will be available in the next release of KeystoneJS. – JME Sep 04 '14 at 15:56
  • Brother, can I do the same thing for a MySQL database with KeystoneJS? Basically the problem I've is, I want to show only the post owned by the logged in user if the user is not an admin, if the logged in user is an admin, then I want to show all the posts available in the Post list. What would be the proper way to do this? I did lots of searches to find a solution for this but I couldn't – mastercordy Jul 04 '23 at 22:45