Skip to content

Commit d9cfca5

Browse files
authored
Make sure associations still work when accessed within a non prepared scope (#44)
* Make sure associations still work when accessed within a non prepared scope * Improve non-prepared data code
1 parent 15cc23b commit d9cfca5

File tree

8 files changed

+47
-10
lines changed

8 files changed

+47
-10
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/rails/graphql/request/strategy.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ def resolve_data_for(field, args)
131131
return unless args.size.zero?
132132

133133
if field.try(:dynamic_resolver?)
134-
prepared = prepared_data_for(field)
135-
args << Event.trigger(:resolve, field, self, prepared_data: prepared, &field.resolver)
134+
extra = prepared_data_for(field, with_null: true)
135+
extra = extra === PreparedData::NULL ? EMPTY_HASH : { prepared: extra }
136+
args << Event.trigger(:resolve, field, self, **extra, &field.resolver)
136137
elsif field.prepared_data?
137138
args << prepared_data_for(field)
138139
else
@@ -206,11 +207,14 @@ def safe_store_data(field, value = nil)
206207

207208
# Get the prepared data for the given +field+, getting ready for
208209
# resolve, while ensuring to check prepared data on request
209-
def prepared_data_for(field)
210-
return @data_pool[field] unless field.prepared_data?
211-
212-
prepared = request.prepared_data_for(field).next
213-
prepared unless prepared === PreparedData::NULL
210+
def prepared_data_for(field, with_null: false)
211+
if field.prepared_data?
212+
request.prepared_data_for(field).next
213+
elsif @data_pool.key?(field)
214+
@data_pool[field]
215+
elsif with_null
216+
PreparedData::NULL
217+
end
214218
end
215219

216220
# Simply run the organize step for compilation

lib/rails/graphql/source/active_record_source.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ def build_association_scope(association)
256256
# Once the records are pre-loaded due to +preload_association+, use the
257257
# parent value and the preloader result to get the records
258258
def parent_owned_records(collection_result = false)
259+
# The absence of the prepared data key means we got to a point that we
260+
# don't know the result of the association, so we simply call it
261+
unless event.data.key?(:prepared_data)
262+
return current_value.public_send(field.method_name)
263+
end
264+
259265
data = event.data[:prepared_data]
260266
return collection_result ? [] : nil unless data
261267

lib/rails/graphql/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def self.version
1414
module VERSION
1515
MAJOR = 1
1616
MINOR = 0
17-
TINY = 5
17+
TINY = 6
1818
PRE = nil
1919

2020
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')

test/assets/sqlite.gql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ type LiteShip {
226226
name: String
227227
}
228228

229+
type Sample {
230+
faction: LiteFaction!
231+
}
232+
229233
type _Mutation {
230234
createLiteBase(liteBase: LiteBaseInput!): LiteBase!
231235

@@ -262,6 +266,8 @@ type _Query {
262266
liteShip(id: ID!): LiteShip!
263267

264268
liteShips: [LiteShip!]!
269+
270+
sample: Sample!
265271
}
266272

267273
"""

test/integration/schemas/mysql.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class MySQLRecord < ActiveRecord::Base
66
establish_connection(
77
name: 'mysql',
88
adapter: 'mysql2',
9-
host: ENV.fetch('GQL_MYSQL_HOST', 'localhost'),
9+
host: ENV.fetch('GQL_MYSQL_HOST', '127.0.0.1'),
1010
database: ENV.fetch('GQL_MYSQL_DATABASE', 'starwars'),
1111
username: ENV.fetch('GQL_MYSQL_USERNAME', 'root'),
1212
password: ENV['GQL_MYSQL_PASSWORD'],

test/integration/schemas/sqlite.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,16 @@ def greeting
9595
end
9696

9797
source LiteShip
98+
99+
object 'Sample' do
100+
field :faction, 'LiteFaction', null: false
101+
end
102+
103+
query_fields do
104+
field :sample, 'Sample', null: false
105+
end
106+
107+
def sample
108+
{ faction: LiteFaction.last }
109+
end
98110
end

test/integration/sqlite/star_wars_query_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,13 @@ def test_query_methods_precedence
8888
query EmpireFleet { liteFaction(id: "2") { greeting } }
8989
GQL
9090
end
91+
92+
def test_nested_non_prepared_source
93+
bases = named_list('Death Star', 'Shield Generator', 'Headquarters')
94+
sample = { sample: { faction: { name: 'Galactic Empire', bases: bases } } }
95+
96+
assert_result({ data: sample }, <<~GQL)
97+
query SampleFaction { sample { faction { name bases { name } } } }
98+
GQL
99+
end
91100
end

0 commit comments

Comments
 (0)