Vor kurzem habe ich API mit graphql-ruby implementiert. Rails verfügt über eine praktische Funktion namens polymorph zum Zuordnen von Modellen. Ich werde erklären, wie man dies in graphql mit UnionType ausdrückt.
Stellen Sie sich den Fall vor, in dem die Benutzer- und PetShop-Tabellen in der Dog-Tabelle besitzbar und polymorph sind. Wenn Sie einen Hund mit graphql bekommen, stellen Sie sicher, dass auch die Spalte seines Besitzers (user oder pet_shop) belegt ist.
Lassen Sie uns zunächst den Fall normaler Assoziationen (Gehört zu, Habe viele usw.) überprüfen. Angenommen, Benutzer und Hund sind eins zu viele, wie unten gezeigt.
user.rb
Class User < ApplicationRecord
has_many: dogs
end
dog.rb
Class Dog < ApplicationRecord
belongs_to: user
end
ObjectType Um die im Modell definierte Zuordnung mit graphql-ruby auszudrücken, schreiben Sie ObjectType wie folgt.
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 #Assoziation mit dem Benutzer
end
Wenn Sie ObjectType wie oben definieren, wird bei der Rückgabe des Dog-Objekts auch das zugehörige Benutzerobjekt abgerufen.
Betrachten Sie als nächstes den Fall der polymorphen Assoziation. Neben dem Benutzer besitzt petShop auch einen Hund.
Für polymorph ist die Rials-Modellassoziation wie folgt:
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 Definieren Sie als Nächstes den Objekttyp. Das petShop-Objekt wurde hinzugefügt und das Feld dogType wurde in ownerable geändert, um eine polymorphe Zuordnung anstelle von user anzuzeigen.
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 #Assoziation mit Eigentümer
end
Beachten Sie, dass der Eigentümertyp UnioTypes anstelle von ObjectTypes ist. UnionType wird ab sofort definiert. UnioneType UnioType ist das Herzstück dieses Artikels. Das in dogType definierte Eigentümerobjekt ist als UnionType definiert und unterscheidet zwischen userType und petShopType.
ownerable_type.rb
module UnionTypes
class OwnerableType < Types::BaseUnion
# possible_Deklarieren Sie die Typen, die Typen zugeordnet werden können
possible_types ObjectTypes::UserType, ObjectTypes::PetShopType
#Beschreiben der Zweigverarbeitung
def self.resolve_type(object, _context)
if object.is_a?(User)
ObjectTypes::PostType
elsif object.is_a?(PetShop)
ObjectTypes::ReplyType
end
end
end
end
Wenn Sie wie oben beschrieben schreiben, wird der vom Resolver zurückzugebende Typ beurteilt und Benutzer oder PetShop ausgewählt. (Es sieht nicht nach Rubin aus, aber ...) Query Bei Verwendung von UnionType wird die Abfrage auch auf eine etwas spezielle Weise geschrieben.
query{
dog(id: [dog_id]){
id
ownerable {
__typename #Geben Sie den Typ an
... on User {
id
}
__typename
... on PetShop {
id
}
}
}
}
Sie können den gewünschten Eigentümer auswählen, indem Sie den Typnamen wie oben beschrieben angeben.
Recommended Posts