how to return both error and data in graphql - graphql

There are user and notes fields.
If the notes field exceeds the limit, I want to get an error with the data
But I don't know what to do. (Currently only an error is returned.)
Is it possible to return both the error and the data?
as it
errors = {xx}
to be
data = {user: { notes: []}}
errors = {xx}
my code is as follows
app/graphql/types/object_types/user.rb
module Types
module ObjectTypes
class User < Types::ObjectTypes::BaseObject
graphql_name 'User'
implements GraphQL::Types::Relay::Node
field :notes, [Types::ObjectTypes::Note], null: true do
description ''
argument :date_from, GraphQL::Types::ISO8601Date, required: true
argument :date_to, GraphQL::Types::ISO8601Date, required: true
end
def notes(date_from:, date_to:)
object.notes.date_between(date_from, date_to).tap { |array| raise AppError if array.size > 1000 }
end

Related

How to add element on graphql return fields

Im a newbie in Ruby and GraphQL
Currently i have such Mutations module
module Mutations
class ProductCreate < BaseMutation
# TODO: define return fields
# field :post, Types::PostType, null: false
type Types::ProductType
# TODO: define arguments
argument :title, String, required: true
argument :vendor, String, required: false
argument :store, ID, required: true
# TODO: define resolve method
def resolve(title:, vendor:, store:)
Product.create!(title: title, vendor: vendor, store: store)
end
end
end
and when i call
mutation {
productCreate(input: {store:"61d6f33a58c4dc4e8a1a0536", title: "Sweet new product", vendor: "JadedPixel"})
{
_id
}
}
Result is
{
"data": {
"productCreate": {
"_id": "61de591c58c4dcb08dffafa9"
}
}
}
I would like to add additional paramenter to query and also get additional paramenter in result
So, my question is
What should i change in code
mutation {
productCreate(input: {title: "Sweet new product", productType: "Snowboard", vendor: "JadedPixel"}) {
product {
id
}
}
}
to get result like this
{
"productCreate": {
"product": {
"id": "1071559610"
}
}
}
I found solutions
Just need to change code like this
module Mutations
class ProductCreate < BaseMutation
field :product, Types::ProductType, null: true
# TODO: define arguments
argument :title, String, required: true
argument :vendor, String, required: false
argument :store, ID, required: true
# TODO: define resolve method
def resolve(title:, vendor:, store:)
record = Product.create!(title: title, vendor: vendor, store: store)
{ product: record }
end
end
end
source of an example
https://www.keypup.io/blog/graphql-the-rails-way-part-2-writing-standard-and-custom-mutations

Activeldap: add a value to a multivalued attribute in the active directory

i have a users and groups in my AD.
ou=users, dc=MLT, dc=local
ou=groups, dc=MLT, dc=local
i want to associate the users with the groups using activeldap.
i do that through adding the users distinguish name (user.dn) to an attribute in the groups called "member" which is multivalued attribute.
you can hier read the description of "member"
https://learn.microsoft.com/en-us/windows/win32/ad/group-objects
This is the Ruby code that I wrote :
config = {
host: 'c',
base: 'dc= MLT,dc=local',
bind_dn: ENV['AD_SERVICE_USER'],
password: ENV['AD_SERVICE_PASSWORD']
}
# Connect to LDAP server
ActiveLdap::Base.setup_connection config
class Group < ActiveLdap::Base
query = {
dn_attribute: 'cn',
prefix: 'ou=groups',
classes: %w[top group]
}
ldap_mapping query
end
class User < ActiveLdap::Base
query = {
dn_attribute: 'cn',
prefix: 'ou=users'
}
ldap_mapping query
end
# associate "Joe" to the "employee" group
group = Group.find(:first, attribute: 'cn', value: 'employee')
user = User.find(:first, attribute:'cn', value:'Joe')
# I used push to add the new user.dn because "member" should be a list of distinguished names.
group.member.push(user.dn)
begin
group.save
rescue ActiveLdap::SaveError
puts 'Could not save group!'
puts new_group.errors.full_messages
end
I became this error message:
undefined method `push' for #<ActiveLdap::DistinguishedName:0x00007f8d2054cb58>
can anyone tell me how can I add more than one value to member ????

How do I accept field arguments for a nested query in Graphql Ruby?

I'm getting this error in GraphQl (Apollo JS/ Graphql Ruby):
Error Error: GraphQL error: Field 'pagination' doesn't accept argument 'pagination' GraphQL error: Variable $pagination is declared by Clients but not used. Reload the page and try again.
I have this query:
query Clients($pagination: PaginationInput) {
clients {
data {
....Fragment
}
pagination(pagination: $pagination) {
....Fragment
}
}
}
And I have this as my input type:
class PaginatedClientsType < Types::BaseObject
field :data, ...
field :pagination, PaginationType ... do
argument :pagination, PaginationInput, required: false
end
end
And this in my query_type.rb file:
field :clients, ::Types::Paginated::ClientsType, null: false do
argument :pagination, PaginationInput, required: false
end
def clients(pagination:)
...
end
// and i've added to no avail:
field :pagination ... do
argument :pagination, PaginationInput, required: false
end
def pagination(pagination:)
...
end
Any ideas on how I can pass the argument to something other than this top level client?
I've read docs here but can't figure it out.
Thanks!

passing arguments in graphQL queries

I'm just starting to learn GraphQL and I'm currently trying to create a clone of twitter. In the code below, is there a way I can pass the 81 from the id argument (e.g. user(id: 81)) automatically to the userId argument (e.g. tweets(userId: 81))?
I've copied my code below
{
user(id: 81) {
username
email
tweets(userId: 81) {
content
}
}
}
user_type.rb
module Types
class UserType < Types::BaseObject
field :username, String, null: false
field :email, String, null: false
field :bio, String, null: true
field :tweets, [Types::TweetType], null: true do
argument :user_id, ID, required: true
end
def tweets(user_id:)
Tweet.where(user_id: user_id)
end
end
end
tweet_type.rb
module Types
class TweetType < Types::BaseObject
field :id, ID, null: false
field :content, String, null: false
field :userId, ID, null: false
field :createdAt, GraphQL::Types::ISO8601DateTime, null: false
field :user, Types::UserType, null: false
end
end
query_type.rb
module Types
class QueryType < Types::BaseObject
field :tweets,
[Types::TweetType],
null: false,
description: "Returns a list of all tweets"
field :user,
Types::UserType,
null: false,
description: "Returns a list of all users" do
argument :id, ID, required: true
end
def tweets
Tweet.all
end
def user(id:)
User.find(id)
end
end
end
GraphQL has a first-class way to factor dynamic values out of the query, and pass them as a separate dictionary (variables). You would use syntax similar to that below, and can read more about it here.
query User($id: Int) {
user(id: $id) {
username
email
tweets(userId: $id) {
content
}
}
}

get name of failed constraints

Assume I have a User class that has a username property and there are several constraints defined on this field.
class User {
String username
static constraints = {
username blank: false, unique: true, email: true
}
}
If I call
user.save()
I can then figure out if any of the constraints on the username field failed via
user.errors['username'] != null
But is there a way I can figure out which of the constraints failed?
The value user.errors['username'].codes will contain a number of keys used for looking up validation messages in messages.properties. You can use these to figure out which constraints broke.
For example, user.errors['username'].codes[-1] will contain the constraint part of the messages.properties key:
assert user.errors['username'].codes[-1] == 'blank' // if blank constraint fails
assert user.errors['username'].codes[-1] == 'unique' // if unique constraint fails
Yeap, you can check the error code with code property on the error object:
def user = new User(email: '')
user.validate()
assert user.errors['email'].code == 'blank'
user.email = 'asdasd'
user.validate()
assert user.errors['email'].code == 'email.invalid'
If you may have more than one error in a property, the only way i found to get all the errors for that property is to iterate the allErrors property:
class Foo {
String bar, baz
static constraints = {
bar blank: false
baz email: true, notEqual: 'foobar'
}
}
def foo = new Foo(bar: '', baz: 'foobar')
foo.validate()
foo.errors.allErrors.each {
println "$it.field: $it.code"
}
Should output something like:
bar: blank
baz: notEqual
baz: email.invalid

Resources