{"id":13879412,"url":"https://github.com/mrrooijen/graphql_activerecord_autoselect","last_synced_at":"2025-10-09T04:19:45.813Z","repository":{"id":56875179,"uuid":"275679085","full_name":"mrrooijen/graphql_activerecord_autoselect","owner":"mrrooijen","description":"Automatic ActiveRecord column selection for GraphQL (Ruby) fields.","archived":false,"fork":false,"pushed_at":"2022-01-20T12:59:15.000Z","size":21,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-17T12:47:59.587Z","etag":null,"topics":["activerecord","graphql","ruby"],"latest_commit_sha":null,"homepage":"https://github.com/mrrooijen/graphql_activerecord_autoselect","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrrooijen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-28T22:29:06.000Z","updated_at":"2022-02-23T16:15:26.000Z","dependencies_parsed_at":"2022-08-20T10:40:35.968Z","dependency_job_id":null,"html_url":"https://github.com/mrrooijen/graphql_activerecord_autoselect","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrrooijen%2Fgraphql_activerecord_autoselect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrrooijen%2Fgraphql_activerecord_autoselect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrrooijen%2Fgraphql_activerecord_autoselect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrrooijen%2Fgraphql_activerecord_autoselect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrrooijen","download_url":"https://codeload.github.com/mrrooijen/graphql_activerecord_autoselect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226143895,"owners_count":17580245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activerecord","graphql","ruby"],"created_at":"2024-08-06T08:02:20.254Z","updated_at":"2025-10-09T04:19:40.774Z","avatar_url":"https://github.com/mrrooijen.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# GraphQL ActiveRecord AutoSelect\n\n[![Gem Version](https://badge.fury.io/rb/graphql_activerecord_autoselect.svg)](https://badge.fury.io/rb/graphql_activerecord_autoselect)\n[![Test Status](https://github.com/mrrooijen/graphql_activerecord_autoselect/workflows/Test/badge.svg)](https://github.com/mrrooijen/graphql_activerecord_autoselect/actions)\n\nAutomatic [ActiveRecord] column selection for [GraphQL (Ruby)] fields.\n\nThis library was developed for- and extracted from [HireFire].\n\nThe documentation can be found on [RubyDoc].\n\n\n### Compatibility\n\n- Ruby 2.7+\n- ActiveRecord 6.0+\n- GraphQL (Ruby) 1.9+\n\n\n### Installation\n\nAdd the gem to your Gemfile and run `bundle`.\n\n```ruby\ngem \"graphql_activerecord_autoselect\", \"~\u003e 2\"\n```\n\n\n### Example\n\n```ruby\nclass Types::Actor \u003c Types::Base::Object\n  using GraphQLActiveRecordAutoSelect\n\n  field :organizations, Types::Organization, null: false, extras: [:lookahead]\n\n  def organizations(lookahead:)\n    object.organizations.autoselect(lookahead)\n  end\n\n  field :organization, Types::Organization, null: false, extras: [:lookahead] do\n    argument :id, ID, required: true\n  end\n\n  def organization(id:, lookahead:)\n    object.organizations.autoselect(lookahead).find(id)\n  end\nend\n```\n\nIn this example an actor has many organizations. We allow the client to query all of the actor's organizations, or a specific one by id. We acquire the lookahead functionality provided by GraphQL Ruby and pass it to `autoselect`.\n\nThe `autoselect` method is made available to ActiveRecord::Base at the class level, as well as to all instances of ActiveRecord::Relations, in classes where the GraphQLActiveRecordAutoSelect refinement is used (`using GraphQLActiveRecordAutoSelect`).\n\nIf you submit the following query to the server:\n\n```\nquery {\n  actor {\n    organizations {\n      name\n      time_zone\n    }\n  }\n}\n```\n\nIt'll translate this:\n\n```ruby\nobject.organizations.autoselect(lookahead)\n```\n\nInto this:\n\n```ruby\nobject.organizations.select(:id, :actor_id, :name, :time_zone)\n```\n\nNotice that it didn't only select the `:name` and `:time_zone` fields, but `:id` and `:actor_id` as well. These kinds of identifiers are always selected in order to avoid potential lookup issues on other relations where they're mandatory.\n\nThe following fields are always selected:\n\n* The primary key field (typically id)\n* The type field\n* Fields that end in _id\n* Fields that end in _type\n\nThe example above builds a select on a has many relation, but the same works for belongs to.\n\n```ruby\nclass Types::Organization \u003c Types::Base::Object\n  using GraphQLActiveRecordAutoSelect\n\n  field :actor, Types::Actor, null: false, extras: [:lookahead]\n\n  def actor(lookahead:)\n    Actor.autoselect(lookahead).find(object.actor_id)\n  end\nend\n```\n\nAnd with this query:\n\n```\nquery {\n  organization {\n    actor {\n      email\n    }\n  }\n}\n```\n\nIt'll translate this:\n\n```ruby\nActor.autoselect(lookahead).find(object.actor_id)\n```\n\nInto this:\n\n```ruby\nActor.select(:id, :email).find(object.actor_id)\n```\n\n\n#### Dependents\n\nYou might have fields or methods that depend on the presence of one or more fields. You can specify dependents to ensure that the requested field or method will be able to successfully compute:\n\n```ruby\nclass Actor \u003c ActiveRecord::Base\n  def secret\n    decrypt(secret_digest)\n  end\n\n  private\n\n  def decrypt(column)\n    # ...\n  end\nend\n\nclass Types::Actor \u003c Types::Base::Object\n  # ...\n\n  field :email, String, null: false\n  field :full_name, String, null: false\n  field :secret, String, null: false\n\n  def self.dependents\n    {\n      :full_name =\u003e [:first_name, :last_name],\n      :secret    =\u003e [:secret_digest],\n    }\n  end\n\n  def full_name\n    \"#{object.first_name} #{object.last_name}\"\n  end\n\n  # ...\nend\n\nclass Types::Organization \u003c Types::Base::Object\n  using GraphQLActiveRecordAutoSelect\n\n  field :actor, Types::Actor, null: false, extras: [:lookahead]\n\n  def actor(lookahead:)\n    Actor.autoselect(lookahead, Types::Actor.dependents).find(object.actor_id)\n  end\nend\n```\n\nThere's a few things to note here.\n\n1. We've defined the `secret` method in the Actor model which decrypts and returns the encrypted data stored in the `secret_digest` column.\n2. We've defined `self.dependents` on the `Types::Actor` class which describes which fields depend on what columns.\n3. We've passed in that dependent configuration to the second argument of `autoselect`.\n\nWe're essentially telling autoselect that if the client selects the `full_name` field, that it has to select the `first_name` and `last_name` columns on the model. Likewise, when selecting the `secret` field, it'll select the `secret_digest` column on the model so that it has the encrypted data it needs to decrypt and return.\n\n```\nquery {\n  organization {\n    actor {\n      email\n      full_name\n      secret\n    }\n  }\n}\n```\n\nIt'll translates this:\n\n```ruby\nActor.autoselect(lookahead, Actor.dependents).find(object.actor_id)\n```\n\nInto this:\n\n```ruby\nActor.select(:id, :email, :first_name, :last_name, :secret_digest).find(object.actor_id)\n```\n\nSince we've selected the `full_name` and `secret` fields, autoselect selects the `first_name`, `last_name`, and `secret_digest` columns, as these are necessary in order to compute `full_name` and `secret`.\n\n\n### Contributing\n\nBug reports and pull requests are welcome on GitHub at:\n\nhttps://github.com/mrrooijen/graphql_activerecord_autoselect\n\nTo install the dependencies:\n\n```\n$ bundle\n```\n\nTo open an interactive console:\n\n```\n$ bundle console\n```\n\nTo run the tests:\n\n```\n$ bundle exec rake\n```\n\nTo view the code coverage (generated after each test run):\n\n```\n$ open coverage/index.html\n```\n\nTo run the local documentation server:\n\n```\n$ bundle exec rake doc\n```\n\nTo build a gem:\n\n```\n$ bundle exec rake build\n```\n\nTo build and install a gem on your local machine:\n\n```\n$ bundle exec rake install\n```\n\nFor a list of available tasks:\n\n```\n$ bundle exec rake --tasks\n```\n\n\n### Author / License\n\nReleased under the [MIT License] by [Michael van Rooijen].\n\n[Michael van Rooijen]: https://michael.vanrooijen.io\n[HireFire]: https://www.hirefire.io\n[RubyDoc]: https://rubydoc.info/github/mrrooijen/graphql_activerecord_autoselect/master\n[MIT License]: https://github.com/mrrooijen/graphql_activerecord_autoselect/blob/master/LICENSE.txt\n[GraphQL (Ruby)]: https://github.com/rmosolgo/graphql-ruby\n[ActiveRecord]: https://github.com/rails/rails/tree/master/activerecord\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrrooijen%2Fgraphql_activerecord_autoselect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrrooijen%2Fgraphql_activerecord_autoselect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrrooijen%2Fgraphql_activerecord_autoselect/lists"}