Skip to content

RStankov/SearchObjectGraphQL

Repository files navigation

Gem Version Code Climate Code coverage

SearchObject::Plugin::GraphQL

SearchObject plugin for GraphQL Ruby.

Installation

Add this line to your application's Gemfile:

gem 'search_object_graphql'

And then execute:

$ bundle

Or install it yourself as:

$ gem install search_object_graphql

Require manually in your project

require 'search_object'
require 'search_object/plugin/graphql'

Dependencies

  • SearchObject >= 1.2
  • Graphql >= 1.5

Changelog

Changes are available in CHANGELOG.md

Usage

Just include the SearchObject.module and define your search options and their types:

class PostResolver < GraphQL::Schema::Resolver
  include SearchObject.module(:graphql)

  type [PostType], null: false

  scope { Post.all }

  option(:name, type: String)       { |scope, value| scope.where name: value }
  option(:published, type: Boolean) { |scope, value| value ? scope.published : scope.unpublished }
end

Then you can just use PostResolver as GraphQL::Schema::Resolver:

field :posts, resolver: PostResolver

Options are exposed as arguments in the GraphQL query:

posts(name: 'Example') { ... }
posts(published: true) { ... }
posts(published: true, name: 'Example') { ... }

Example

You can find example of most important features and plugins - here.

Features

Documentation

Search object itself can be documented, as well as its options:

class PostResolver < GraphQL::Schema::Resolver
  include SearchObject.module(:graphql)

  description 'Lists all posts'

  option(:name, type: String, description: 'Fuzzy name matching') { ... }
  option(:published, type: Boolean, description: 'Find published/unpublished') { ... }
end

Default Values

class PostResolver < GraphQL::Schema::Resolver
  include SearchObject.module(:graphql)

  scope { Post.all }

  option(:published, type: Boolean, default: true) { |scope, value| value ? scope.published : scope.unpublished }
end

Additional Argument Options

Sometimes you need to pass additional options to the graphql argument method.

class PostResolver < GraphQL::Schema::Resolver
  include SearchObject.module(:graphql)

  scope { Post.all }

  option(:published, type: Boolean, argument_options: { pundit_role: :read }) { |scope, value| value ? scope.published : scope.unpublished }
end

Accessing Parent Object

Sometimes you want to scope posts based on parent object, it is accessible as object property:

class PostResolver < GraphQL::Schema::Resolver
  include SearchObject.module(:graphql)

  # lists only posts from certain category
  scope { object.posts }

  # ...
end

If you need GraphQL context, it is accessible as context.

Enums Support

class PostSearch
  include SearchObject.module(:graphql)

  OrderEnum = GraphQL::EnumType.define do
    name 'PostOrder'

    value 'RECENT'
    value 'VIEWS'
    value 'COMMENTS'
  end

  option :order, type: OrderEnum, default: 'RECENT'

  def apply_order_with_recent(scope)
    scope.order 'created_at DESC'
  end

  def apply_order_with_views(scope)
    scope.order 'views_count DESC'
  end

  def apply_order_with_comments(scope)
    scope.order 'comments_count DESC'
  end
end

Relay Support

Search objects can be used as Relay Connections:

class PostResolver < GraphQL::Schema::Resolver
  include SearchObject.module(:graphql)

  type PostType.connection_type, null: false

  # ...
end
field :posts, resolver: PostResolver

Running tests

Make sure all dependencies are installed with bundle install

rake

Release

rake release

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Run the tests (rake)
  6. Create new Pull Request

Authors

See also the list of contributors who participated in this project.

License

MIT License