Polymorphic associations are used in cases when there are several one-to-many relationships that you could aggregate because for all the parents, the children are similar.
In other words, a polymorphic association allows for a table to have multiple types of parents.
Lets say you have products and reviews in the system . Both have to be tagged. A naive implementation would be to create two one to many relationships:
- Product has many ProductTag(s)
- Review has many ReviewTag(s)
This will work? kind of, but it will violate a DRY principle because the
REVIEW_TAG tables will be identical (except for names!).
A better approach would be to use Polymorphic associations. In the Polymorphic associations , you would create one table called
TAGS, and add two columns to this table, besides the ones that you need:
After this, you will need to provide one last bit of information to the framework by specifying relationships:
This annotation tells ActiveJDBC that Product has many Tags as well as Review has many tags too. The annotation itself is easy to understand if you read it aloud.
Operations are the same as with One-to-many associations
Adding and searching for polymorphic children
Product p = Product.findById(100); p.add(Tag.create("tag", "basket")); p.add(Tag.create("tag", "toy")); List<Tag> tags = p.getAll(Tag.class); ...iterate Review customerReview = Review.findById(2024); customerReview.add(Tag.create("tag", "fun")); customerReview.add(Tag.create("tag", "useful")); List<Tag> tags = customerReview.getAll(Tag.class); ... iterate
The table TAG content might look like this after operations above:
Conditional search for polymorphic children
getAll(type) method returns all relations, the
get(type) method allows for a selection criteria on the child table:
Removing polymorphic children
Removing children is as easy as expected;
This will remove a child record from the
Deleting polymorphic parents
When deleting a record that is a parent to polymorphic children, you have two options:
- Only delete the parent itself. This will leave orphan children:
- Delete parent along with all the children:
The latter will delete the parent along with all associated polymorphic children. See Delete cascade for more information.
Finding polymorphic parent
Navigate from children to parents in relationships:
Override standard parent type values
In some cases, it is not possible to have a fully qualified class name in the
parent_type column. This is usually a case when the same table backs a different ORM which also supports polymorphic associations (Ruby on Rails ActiveRecord for example).
When faced with this problem, you can use annotation to override default behavior:
This defines polymorphic associations between models Classification, Mammal and Vehicle, such that the
parent_type column of
CLASSIFICATIONS table will contain values
Mammal for corresponding parent records from
MAMMAL tables. The order of parent classes and type labels is important, they must correspond to one another.
Here is an example of CLASSIFICATIONS table:
How to comment
The comment section below is to discuss documentation on this page.
If you have an issue, or discover bug, please follow instructions on the Support page