Skip to content

Commit

Permalink
Add custom associations for fields
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoyce committed Sep 8, 2021
1 parent 4837b9e commit 65e0548
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
graphql-eager_load (0.2.2)
graphql-eager_load (0.2.3)

GEM
remote: https://rubygems.org/
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,27 @@ users {

The output of the `#associations_to_eager_load` helper method would be `{estimates: {}, profile_photo: {blob: {}}`. Without the `.allow_include_builder_fields` class method the output would be `{estimates: {}}`.

If you have a field that is derived from an association, but the association is not included in the query, you can define a `#custom_associations_for_fields` method to specify which associations to include for a specific field.

```ruby
module Types
class User < Types::Base
field :estimates, [Types::Estimate], null: false
field :org_names, [String], null: true

def org_names
object.orgs.map(&:name)
end

def self.custom_associations_for_fields
{
org_names: [:org]
}
end
end
end
```

## Development

After checking out the repo, run `bundle` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bundle exec bin/console` for an interactive prompt that will allow you to experiment.
Expand Down
12 changes: 12 additions & 0 deletions lib/graphql/eager_load/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def self.call(selections:, model:)
else
includes.merge!(builder.includes)
end

includes.deep_merge!(builder.custom_associations_for_selection)
end
end

Expand All @@ -66,6 +68,16 @@ def active_storage_attachment?
model.reflect_on_attachment(field_name).present?
end

def custom_associations_for_selection
return {} unless field_owner.respond_to?(:custom_associations_for_fields)

custom_associations = field_owner.custom_associations_for_fields[field_name.to_sym]

return {} unless custom_associations

custom_associations.map { |association| [association, {}] }.to_h
end

private

attr_reader :selection, :model
Expand Down
2 changes: 1 addition & 1 deletion lib/graphql/eager_load/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def associations_to_include
graphql_eager_load_options(model: self.class.class_variable_get(:@@eager_load_model))
end

def graphql_eager_load_options(selections: context.query.lookahead.selections, model:)
def graphql_eager_load_options(model:, selections: context.query.lookahead.selections)
Builder.call(selections: selections, model: model)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/graphql/eager_load/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Graphql
module EagerLoad
VERSION = '0.2.2'
VERSION = '0.2.3'
end
end
21 changes: 21 additions & 0 deletions spec/graphql/eager_load_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,26 @@
)
end
end

describe 'custom_associations_for_fields' do
let(:model) { ::User }
let(:query_string) do
<<-QUERY
query {
users {
nodes {
email
}
}
}
QUERY
end

it 'includes the specified associations' do
expect(options).to eq(
jobs: {}
)
end
end
end
end
7 changes: 7 additions & 0 deletions spec/internal/app/graphql/types/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class User < GraphQL::Schema::Object
field :proposal_documents, [ProposalDocument], null: false
field :order, Order, null: false
field :photo, Types::File, null: true
field :email, String, null: true

def order
{ code: SecureRandom.uuid }
Expand All @@ -19,5 +20,11 @@ def photo
def self.allow_include_builder_fields
[:photo]
end

def self.custom_associations_for_fields
{
email: [:jobs]
}
end
end
end

0 comments on commit 65e0548

Please sign in to comment.