Greyhounddad
Greyhounddad

Reputation: 115

Using resolvers to get more complex queries in GraphQL and Ruby

Trying to learn GraphQL in a Ruby on Rails API I am using the graphql gem.

In this example, I have products and review, the product can have many reviews and review belongs to one product. Reviews have comment:string and stars:int. I have everything working so I can return all products with all the reviews. I also know how to return a single product with all the reviews.

What I am now after is all products then all reviews that have a star rating greater than 3.

so I would kind of assume something like

{ 
     products{
           reviews(where: "stars< 3") {
                  stars
           }
     }
}

But I would like

{
    products{
        reviews {
              stars
         }
     }
}

to also work and return all reviews if its possible

Most tutorial I have seen are in js... use some -> resolver(obj,arg,ctx) syntax that looks to be no longer valid for ruby.

Or does the generic grab all records.

query_type.rb

field :product, ProductType, null: false, description: "find product by id"do
      argument :id, ID, required: true
    end

field :products, [ProductType], null: false

def products
    Product.all
end

def product(id:)
    Product.find(id)
end

product_type.rb

module Types
  class ProductType < Types::BaseObject
    description " A product"

    field :id, ID, null: false
    field :title, String, null: false
    field :category, Types::CategoryType, null: false
    field :reviews, [Types::ReviewType], null: false
  end
end

review_type.rb

module Types
  class ReviewType < Types::BaseObject
    field :id, ID, null: false
    field :content, String, null: false
    field :stars, Integer, null: false
    field :product, Types::ProductType, null: false
  end
end

I would like to be able to pass reviews in and get all of them but also to be able to use where clauses in there.

What's the best way of doing this?

Upvotes: 1

Views: 485

Answers (1)

Nithin
Nithin

Reputation: 3699

How about something like this.

FE query look like

{ 
  products{
        reviews(rating_lower_limit: 1, rating_higher_limit: 3) {
               stars
        }
  }
}

product_type.rb

field :reviews, [Types::ReviewType], null: false do
  argument :rating_lower_limit, Integer, required: false
  argument :rating_higher_limit, Integer, required: false
end

def reviews(rating_lower_limit:, rating_higher_limit:)
  _reviews = object.reviews
  if (rating_lower_limit && rating_higher_limit)
    _reviews.where(stars: rating_lower_limit..rating_higher_limit)
  else
    _reviews
  end
end

Untested. But you get the idea.

Upvotes: 1

Related Questions