is_model_object.rb 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Concern::IsModelObject
  3. extend ActiveSupport::Concern
  4. included do
  5. implements GraphQL::Types::Relay::Node
  6. global_id_field :id
  7. # Make sure that objects in subdirectories do not get only the class name as type name,
  8. # but also the parent directories.
  9. graphql_name name.sub('Gql::Types::', '').gsub('::', '').sub(%r{Type\Z}, '')
  10. field :created_at, GraphQL::Types::ISO8601DateTime, null: false, description: 'Create date/time of the record'
  11. field :updated_at, GraphQL::Types::ISO8601DateTime, null: false, description: 'Last update date/time of the record'
  12. if name.eql? 'Gql::Types::UserType'
  13. field :created_by_id, Integer, null: false, description: 'User that created this record'
  14. field :updated_by_id, Integer, null: false, description: 'Last user that updated this record'
  15. else
  16. belongs_to :created_by, Gql::Types::UserType, null: false, description: 'User that created this record'
  17. belongs_to :updated_by, Gql::Types::UserType, null: false, description: 'Last user that updated this record'
  18. end
  19. end
  20. class_methods do
  21. # Using AssociationLoader with has_many and has_and_belongs_to_many didn't work out,
  22. # because the ConnectionTypes generate their own, non-preloadable queries.
  23. # See also https://github.com/Shopify/graphql-batch/issues/114.
  24. def belongs_to(association, *args, **kwargs, &block)
  25. kwargs[:resolver_method] = association_resolver(association) do
  26. definition = object.class.reflections[association.to_s]
  27. id = object.public_send(:"#{definition.plural_name.singularize}_id")
  28. Gql::RecordLoader.for(definition.klass).load(id)
  29. end
  30. field(association, *args, **kwargs, &block)
  31. end
  32. def has_one(association, *args, **kwargs, &block) # rubocop:disable Naming/PredicateName
  33. kwargs[:resolver_method] = association_resolver(association) do
  34. definition = object.class.reflections[association.to_s]
  35. Gql::RecordLoader.for(definition.klass, column: definition.foreign_key).load(object.id)
  36. end
  37. field(association, *args, **kwargs, &block)
  38. end
  39. private
  40. def association_resolver(association, &block)
  41. :"resolve_#{association}_association".tap do |resolver_method|
  42. define_method(resolver_method, &block)
  43. end
  44. end
  45. end
  46. end