passing arguments in graphQL queries - graphql

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
}
}
}

Related

how to return both error and data in 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

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

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!

Mongo, Mongoid join data from different models in Ruby on Rails

I'm adapting a Ruby on Rails application to work with MongoDB instead of PostgreSQL. I have this 2 class:
module Cms
class Content
include Mongoid::Document
include Mongoid::Orderable
field :title, type: String
field :position, type: String
field :text_body, type: String
field :expiration_date, type: Date
field :active, type: Boolean, default: false
validates :title, :text_body, presence: true
orderable base: 0
belongs_to :cms_content_category, class_name: 'Cms::ContentCategory'
scope :ordered, ->() { order(position: :asc) }
scope :not_expired, ->() { any_of({ expiration_date: nil }, { :expiration_date.gte => Date.today }) }
end
end
module Cms
class Submenu
include Mongoid::Document
include Mongoid::Orderable
field :title, type: String
field :position, type: String
field :external_url, type: String
field :open_as, type: String, default: '_self'
field :active, type: Boolean, default: false
delegate :url_helpers, to: :'Rails.application.routes'
validates :title, presence: true
validates :external_url, presence: true, if: Proc.new { |obj| obj.cms_content_id.nil? }
validates :cms_content_id, presence: true, if: Proc.new { |obj| obj.external_url.blank? }
orderable base: 0
belongs_to :cms_content, class_name: 'Cms::Content'
belongs_to :cms_menu, class_name: 'Cms::Menu'
scope :ordered, ->() { order(position: :asc) }
def url
self.external_url.present? ? self.external_url : url_helpers.content_show_path(self.cms_content_id)
end
end
end
The problem is that I don't know how to adapt the following SQL query to work with MongoDB.
scope :active, joins("FULL JOIN contents ON contents.id = cms_submenus.content_id")
.where("cms_submenus.active IS TRUE AND (
(cms_submenus.content_id IS NOT NULL AND ((contents.expiration_date >= :today OR expiration_date IS NULL) AND contents.archived IS NOT TRUE)) OR
(cms_submenus.external_url IS NOT NULL AND cms_submenus.external_url <> '')
)", today: Date.today)
This scope has to be called from Submenu model.
Someone has an idea on how to solve this problem?
I'm using Rails 4.2.0 with Ruby 2.2.0 and Mongoid 4.0.2 with MongoDB 2.6.8.
thank you

How to efficiently retry after failing Mongoid uniqueness validation?

I have a Mongoid model which requires two fields to be unique. I want to generate the "unique number" value and retry if it becomes not unique in the time it took to save.
class MyModel
include Mongoid::Document
include Mongoid::Timestamps
field :number
field :name
index({ number: 1 }, { unique: true, background: true })
index({ name: 1 }, { unique: true, background: true })
validates_presence_of :number, :name
validates_uniqueness_of :number, :name
def self.make!(name)
find_or_initialize_by(name: name).tap do |model|
if model.new_record?
model.number = generate_random_number
model.save! # fails validation because number is no longer unique
end
end
end
end
How can I retry when the uniqueness collision happens?
Begin
Rescue
Retry
Check
this example

Resources