The ability to create polymorphic one-to-one, one-to-many, and many-to-many relationships in Hasura. This would necessitate Hasura generating appropriate union or interface graphql types for the polymorphic association (or some way for the user to create these types).
contact list which contains both person and organization subscribers._union or interface types).people, organizations, events, and addresses tables.address_id column to the people, organizations, and events tables which acts as a foreign key to an address record. However, this does not allow you to automatically delete the address associated with a Person, Organization, or Event.people table. It would be nice if Hasura supplied an option to create this trigger for you.person_addresses, organization_addresses, and event_addresses tables instead of a single addresses table. However this denormalizes your database schema and unnecessarily complicates the generated graphql schema.many-to-many association with both Person and Organization records.organization_subscription and person_subscription join tables. If a graphql client wants to be able to pull the first 10 subscribers of a contact list in alphabetical order, you must create a custom sql view. Problematically, the graphql associated with this custom SQL view cannot return an interface/union type of organization and person records. This can be worked around by returning an artificial subscription object with person and organization properties which would contain either a person or organization. However jumping through these hoops is not ideal.As an example, Rails' Active Record supports polymorphic associations by utilizing an additional type column for associations. The type column contains the name of the table, while the standard foreign key column contains the id of the table row.
addresses table might model its polymorphic association using owner_id and owner_type columns. The owner_type column would contain the table of the address owner (either people, organizations, or events) while the owner_id column would contain the row id of the address owner.A major problem with the Active Record solution is that its logic is handled outside of the database in the ruby application. Active Record does not utilize a foreign key constraint for polymorphic associations because postgres can't handle that scenerio. i.e. the Hasura graphql-engine server would be handling the logic, checking for the existance of foreign records, etc. This strategy would likely run into major problems around concurrency and would be a major change for hasura, which seems to delegate as much logic as possible to the database.
Doing a bit of research, I've found a few helpful stackoverflow answers on how to handle polymorphic associations within the database:
The major takeaway is that postgres/sql does not formally support polymorphic associations. Given that polymorphic associations are a very common part of many data models though, and given that polymorphic associations are a widely used aspect of graphql, it seems worthwhile to find a way of supporting them within Hasura.
Since there doesn't appear to be an "official" way to support polymorphic associations, Hasura would need to take an opinionated route here (which, personally, I think is fine). The super-table / sub-table approach described in this Stackoverflow answer seems like a good solution: https://stackoverflow.com/a/4970646/5490505.
A super-table / sub-table approach would allow for describing both graphql interface types and union types (an interface type would be described by the super-table. A union type would also be described by the super table, but the super-table wouldn't contain any information other than id). Hasura would take care of joining the tables and presenting a single record to the graphql client. Hasura would also take care of handling mutations as if only a single table were being updated. Unfortunately, a super/sub table approach still wouldn't allow for cascade deletion of a polymorphic association (perhaps automatically generating postgres triggers could help with this).
Laravel eloquent also has very nice polymorphic relations implemented
https://laravel.com/docs/eloquent-relationships
@Youhan Looks like Laravel takes the same approach as ActiveRecord. As I pointed out in the "possible implementations" section above, while that strategy is pretty easy to implement at the graphql-engine level (i.e. not the database level), I think it's probably a non-starter for Hasura for the reasons outlined above.
Any updates on that?
Heyy, is it kosher to allow overriding of __typename, seems like we could easily get this to work, or is that too hacky?
TABLE Entity
id
TABLE entity_customer_types
entity_id
customer_id_for_type
__typename | <type goes here in text> eg. "CustomerType1"
TABLE CustomerType1
id
name
type_1_field
TABLE CustomerType2
id
name
type_2_field
########
# Usage:
########
Query {
Entity {
entity_customer_types {
__typename
... on CustomerType1 {
name
type_1_field
}
... on CustomerType2 {
name
type_2_field
}
}
}
}
I too come from a Laravel world, and really need polymorphic relations to make things like attaching images to models maintainable. Can we get some input on this becoming an official feature, or an option for the best temporary workaround? Thanks!
@zlanich Have you seen these workarounds? https://github.com/hasura/graphql-engine/issues/1167#issuecomment-444761777
@cllns Yes, and while that is "slightly" better than creating separate tables (from an organization perspective), it still requires you to create a relationship view for every object type. It's still quite clumsy, particularly when coming from a Laravel world where you don't need to do this. You just specify a morph-map that transforms the active record classes into slugs like "model-name", then it handles the rest for you. I'm really hoping for proper support for polymorphic relations at some point :(
I really like to see this feature. The absence actually keeps us from adopting hasura.
Most helpful comment
Any updates on that?