for polymorphic association, how to create relationship.
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
create_table :pictures do |t|
t.string :name
t.integer :imageable_id
t.string :imageable_type
t.timestamps
end
how to create relationship, so i can query like this
{
products {
name
pictures {
id
name
}
}
}
thanks !
@dfang I have put together a demo with the schema you noted above: https://relationship-demo.herokuapp.com
Let me know how it goes.
@shahidhk i see, it works.
you create two tables, product_pictures, employee_pictures. when you insert, you need insert data to at least two tables(eg. pictures and product_pictures). normally in rails, we only insert data to pictures. ProductPicture is only pure model.
and if you have another types of pictures, you need to create new tables.
similarly, commentable, likeable, you need to create as many as sub tables.
thanks !
@shahidhk In your experience, which schema style will perform better on Postgres and Hasura?
pictures table (like your example)employee_pictures and product_pictures@dfang @SkaterDad I am not very familiar with Rails, so I will get back with a more clear understanding.
The Rails way is in the OP. A single table for images, which has columns for the id and type of the related entities.
There are articles arguing that its bad, and other people saying it's good. None are specifically about GraphQL, though, which will impact the types of queries being made.
@dfang @SkaterDad
We don't natively support polymorphic associations like that of Rails, however you'll still be able to query like you wanted. The pictures table will be something along these lines:
pictures:
- id: integer
- name: text
- imageable_id: integer
- imageable_type: text
You can create views as follows:
create view employee_pictures as select * from pictures where imageable_type = 'employees';
create view product_pictures as select * from pictures where imageable_type = 'products';
Now you can define a manual relationship called pictures on employees and products table using these views. So your queries will now look like this:
{
employees {
id
name
pictures {
id
name
}
}
}
Another option is to use through table like @shahidhk suggested, i.e, employee_pictures, product_pictures .. etc. If you have such a modelling, Hasura makes it very easy to insert into these tables using relationships, i.e, you can insert a picture and associate it with an employee in a single query. If you have such a modelling, your queries will look like this:
{
employees {
id
name
pictures {
picture {
id
name
}
}
}
}
So it is up to you to pick a schema design that suits your use case. The GraphQL queries will roughly be the same.
Hi @0x777
Thank you for the solution, nice workaround with views 馃憤
But I do have an issue, after creating my new relationship the UI for data schema crash (JS error) with the message "Something went wrong"
If I remove the relationship directly in the database it works again. I've traced the JS error to this line: https://github.com/hasura/graphql-engine/blob/c3f4c35141f1187fc2f0f107158c1dff26f34568/console/src/components/Services/Data/TableRelationships/autoRelations.js#L110
Here is my faulty hdb_relationship row:
| table_schema | table_name | rel_name | rel_type | rel_def | comment | is_system_defined |
|---|---|---|---|---|---|---|
| public | orders | states | array | {"manual_configuration": {"remote_table": "orders_states", "column_mapping": {"id": "resource_id"}}} | NULL | f |
Did I missed something or this is a bug? Thank you.
Most helpful comment
@dfang @SkaterDad
We don't natively support polymorphic associations like that of Rails, however you'll still be able to query like you wanted. The
picturestable will be something along these lines:You can create views as follows:
Now you can define a manual relationship called
picturesonemployeesandproductstable using these views. So your queries will now look like this:Another option is to use through table like @shahidhk suggested, i.e,
employee_pictures,product_pictures.. etc. If you have such a modelling, Hasura makes it very easy to insert into these tables using relationships, i.e, you can insert a picture and associate it with an employee in a single query. If you have such a modelling, your queries will look like this:So it is up to you to pick a schema design that suits your use case. The GraphQL queries will roughly be the same.