Récemment, j'ai implémenté une API avec graphql-ruby. Rails a une fonction pratique appelée polymorphe pour associer des modèles. J'expliquerai comment exprimer cela en graphql en utilisant UnionType.
Prenons le cas où les tables User et PetShop sont propriétaires et polymorphes dans la table Dog. Lorsque vous obtenez un chien avec graphql, assurez-vous que la colonne de son propriétaire (user ou pet_shop) est également prise.
Tout d'abord, passons en revue le cas des associations normales (appartient_à, has_many, etc.). Supposons que l'utilisateur et le chien soient un-à-plusieurs, comme indiqué ci-dessous.
user.rb
Class User < ApplicationRecord
has_many: dogs
end
dog.rb
Class Dog < ApplicationRecord
belongs_to: user
end
ObjectType Pour exprimer l'association définie dans le modèle avec graphql-ruby, écrivez ObjectType comme suit.
user_type.rb
Class UserType < Types::BaseObject
field :id, ID, null: false
end
dog_type.rb
Class DogType < Type::BaseObject
field :name, String, null: false
field :user, ObjectTypes::UserType, null: false #Association avec l'utilisateur
end
Si vous définissez ObjectType comme ci-dessus, il obtiendra également l'objet utilisateur associé lors du retour de l'objet chien.
Ensuite, considérons le cas de l'association polymorphe. Outre l'utilisateur, petShop possède également un chien.
Pour les polymorphes, l'association du modèle Rials est la suivante:
user.rb
Class User < ApplicationRecord
has_many :dogs, as: :ownerable
end
pet_shop.rb
Class PetShop < ApplicationRecord
has_many :dogs, as: :ownerable
end
dog.rb
Class Dog < ApplicationRecord
belongs_to :ownerable, polymorphic: true
end
ObjectType Ensuite, définissez le type d'objet. L'objet petShop a été ajouté et le champ dogType a été changé en ownerable pour indiquer une association polymorphe au lieu de user.
user_type.rb
Class UserType < Types::BaseObject
field :id, ID, null: false
end
pet_shop_type.rb
Class PetShopType < Types::BaseObject
field :id, ID, null: false
end
dog_type.rb
Class DogType < Type::BaseObject
field :name, String, null: false
field :ownerable, UnionTypes::OwnerableType, null: false #Association avec propriétaire
end
Notez que le type propriétaire est UnioTypes au lieu d'ObjectTypes. UnionType sera défini à partir de maintenant. UnioneType UnioType est au cœur de cet article. Le propriétaire défini dans dogType est défini comme UnionType, et il fait la distinction entre userType et petShopType.
ownerable_type.rb
module UnionTypes
class OwnerableType < Types::BaseUnion
# possible_Déclarer les types qui peuvent être associés aux types
possible_types ObjectTypes::UserType, ObjectTypes::PetShopType
#Décrire le traitement des succursales
def self.resolve_type(object, _context)
if object.is_a?(User)
ObjectTypes::PostType
elsif object.is_a?(PetShop)
ObjectTypes::ReplyType
end
end
end
end
En écrivant comme ci-dessus, il déterminera le type à renvoyer par le résolveur et sélectionnera Utilisateur ou PetShop. (Cela ne ressemble pas à du rubis, mais ...) Query Lors de l'utilisation d'UnionType, la requête est également écrite d'une manière légèrement spéciale.
query{
dog(id: [dog_id]){
id
ownerable {
__typename #Spécifiez le type
... on User {
id
}
__typename
... on PetShop {
id
}
}
}
}
Vous pouvez sélectionner le propriétaire souhaité en spécifiant le nom du type comme décrit ci-dessus.
Recommended Posts