Support and Documentation

@Recordable.Where

Applies to: Field

Allows you to specify a predicate for a reference field of a Record-derived type. This annotation is used for data validation and dynamic lookups in a Brightspot selection field.

Data validation

For data validation, the predicate is evaluated against a value. If the value does not match the predicate, a validation error is thrown.

In this example, the @Where annotation enforces the requirement that new articles be created by authors with an expertise of Exploration.

The Author class includes an expertise field for setting a writer's experience focus.

package content.author;

import com.psddev.cms.db.Content;

public class Author extends Content {

    @Indexed
    private String name;

    @Indexed
    private String expertise;
   
    /* Getters and setters */

}

The Article class applies the @Where annotation on the author field.

package content.article;

import com.psddev.cms.db.Content;
import content.Image;
import content.Author;

public class Article extends Content {
    private String headline;
    private Image leadImage;
    private String body;

    @Where("expertise = 'Exploration'")
    private Author author;
    /* Getters and Setters */

    protected void onValidate() {
        getState().addError(getState().getField("author"), "Select an author with Exploration expertise");
    }
}

In the previous snippet—

  • Lines 17 –19 implement the onValidate callback method in the event that a ValidationException is thrown because an invalid value is set on the author field.

    In Brightspot, if an author is selected without Exploration expertise, the callback sends an extended message for Brightspot to display in the content edit form. (For information about validation time and when it occurs, see Save life cycle.)

    content-form-validation-error.png

When you use the @Where annotation, Brightspot automatically filters results in the content picker based on the predicate set on the annotation. Continuing with the previous example, when a user opens the content picker for the author field, the search finds the authors with Exploration expertise.

content-picker-with-static-where.svg
Dynamic lookups

You can use the @Where annotation to filter results based on values returned by a method, allowing for dynamic lookups in a Brightspot selection field.

The following snippet implements a dynamic lookup for articles in a collection field.

@Where("tags = ?/getTags")
private Set<Article> relatedStories;

In Brightspot, the @Where annotation will filter the collection of articles based on the tags field, another collection field with values generated by the getTags method. The question mark ? represents the current object (similar to Java's keyword this), so the method getTags is a member of the current object.

The following example gives additional context to dynamically filtering a collection of articles based on tags, used to relate like articles. Articles are related when they are set with one or more of the same tags, represented by a Tag object.

package content.article;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

import com.psddev.cms.db.Content;
import com.psddev.cms.db.ToolUi;
import com.psddev.dari.db.Recordable;

public class Article extends Content {

    @Recordable.Required
    private String headline;

    private Image leadImage;

    @ToolUi.RichText
    private String body;

    @Indexed
    private Set<Tag> tags;

    @Where("tags = ?/getTags")
    private Set<Article> relatedStories;

    /* Getters and setters */

    @ToolUi.Hidden
    @Ignored(false)
    public Set<Tag> getTags() {
        if (tags != null) {
            return tags;
        }
        return new HashSet();
    }
}

In the previous snippet—

  • Lines 11–22 declare a content type Article with five fields: headline, lead image, body, tags, and a selection field for a related story.

    content-edit-form-with-where.png
  • Line 21 applies an @Indexed annotation, allowing Dari to search for all the tags associated with a given article.

  • Line 24 applies a dynamic @Where annotation. The annotation populates the relatedStories selection field with articles whose tags are in the set returned by the method getTags.

  • Lines 29–36 implement the method getTags:

    • Line 29 applies the @ToolUi.Hidden annotation, which prevents the method's results from appearing in the content edit form.

    • Line 30 applies the @Ignored(false) annotation, which ensures the method is run when the user clicks on the selection field.

    • Line 31 declares the method's return type, a set of Tag objects.

    • Lines 33 returns a set of tags in the current article (if any). Brightspot uses this list in the @Where annotation to populate the content picker.

      content-picker-with-dynamic-where.svg
    • Line 35 returns an empty set if the current article has no tags.