Skip to content

Commit 6e01e0a

Browse files
authored
Merge pull request #70 from richmolj/runtime_ctx
Allow scopes access to runtime context
2 parents 104adbb + 85e9936 commit 6e01e0a

File tree

11 files changed

+115
-6
lines changed

11 files changed

+115
-6
lines changed

lib/generators/jsonapi/field_generator.rb

Whitespace-only changes.

lib/jsonapi_compliable/scoping/default_filter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Scoping::DefaultFilter < Scoping::Base
3838
def apply
3939
resource.default_filters.each_pair do |name, opts|
4040
next if overridden?(name)
41-
@scope = opts[:filter].call(@scope)
41+
@scope = opts[:filter].call(@scope, resource.context)
4242
end
4343

4444
@scope

lib/jsonapi_compliable/scoping/extra_fields.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Scoping::ExtraFields < Scoping::Base
3535
# @return the scope object we are chaining/modofying
3636
def apply
3737
each_extra_field do |callable|
38-
@scope = callable.call(@scope)
38+
@scope = callable.call(@scope, resource.context)
3939
end
4040

4141
@scope

lib/jsonapi_compliable/scoping/filter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def apply
4141
# specified in the adapter.
4242
def filter_scope(filter, value)
4343
if custom_scope = filter.values.first[:filter]
44-
custom_scope.call(@scope, value)
44+
custom_scope.call(@scope, value, resource.context)
4545
else
4646
resource.adapter.filter(@scope, filter.keys.first, value)
4747
end

lib/jsonapi_compliable/scoping/paginate.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def apply_standard_scope
6161

6262
# Apply the custom pagination proc
6363
def apply_custom_scope
64-
custom_scope.call(@scope, number, size)
64+
custom_scope.call(@scope, number, size, resource.context)
6565
end
6666

6767
private

lib/jsonapi_compliable/scoping/sort.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def apply_standard_scope
3131
# @return the scope we are chaining/modifying
3232
def apply_custom_scope
3333
each_sort do |attribute, direction|
34-
@scope = custom_scope.call(@scope, attribute, direction)
34+
@scope = custom_scope
35+
.call(@scope, attribute, direction, resource.context)
3536
end
3637
@scope
3738
end

spec/extra_fields_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,36 @@ class SerializableTestExtraFields < JSONAPI::Serializable::Resource
99
extra_attribute :net_worth, if: proc { !@context || @context.allow_net_worth? } do
1010
100_000_000
1111
end
12+
13+
extra_attribute :runtime_id do
14+
@context.runtime_id
15+
end
1216
end
1317

1418
before do
1519
resource_class.class_eval do
1620
extra_field :net_worth do |scope|
1721
scope.include_foo!
1822
end
23+
24+
extra_field :runtime_id do |scope, ctx|
25+
scope.runtime_id = ctx.runtime_id
26+
scope
27+
end
1928
end
2029
end
2130

2231
let!(:scope_object) do
2332
scope = Author.all
2433
scope.instance_eval do
34+
def runtime_id=(val)
35+
@runtime_id = val
36+
end
37+
38+
def runtime_id
39+
@runtime_id
40+
end
41+
2542
def include_foo!
2643
self
2744
end
@@ -53,6 +70,21 @@ def include_foo!
5370
expect(json['data'][0]['attributes'].keys).to match_array(%w(first_name last_name net_worth))
5471
end
5572

73+
context 'when accessing runtime context' do
74+
before do
75+
params[:extra_fields] = { authors: 'runtime_id' }
76+
end
77+
78+
it 'works' do
79+
expect(scope_object).to receive(:runtime_id=).with(789)
80+
ctx = double(runtime_id: 789).as_null_object
81+
resource.with_context ctx do
82+
attrs = json['data'][0]['attributes']
83+
expect(attrs['runtime_id']).to eq(789)
84+
end
85+
end
86+
end
87+
5688
context 'when extra field is requested but guarded' do
5789
before do
5890
params[:extra_fields] = { authors: 'net_worth' }

spec/filtering_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
scope.where(['first_name like ?', "#{value}%"])
1515
end
1616
allow_filter :active
17+
allow_filter :temp do |scope, value, ctx|
18+
scope.where(id: ctx.runtime_id)
19+
end
1720
end
1821
end
1922

@@ -27,6 +30,15 @@
2730
expect(scope.resolve.map(&:id)).to eq([author1.id])
2831
end
2932

33+
# For example, getting current user from controller
34+
it 'has access to calling context' do
35+
ctx = double(runtime_id: author3.id).as_null_object
36+
JsonapiCompliable.with_context(ctx, {}) do
37+
params[:filter] = { temp: true }
38+
expect(scope.resolve.map(&:id)).to eq([author3.id])
39+
end
40+
end
41+
3042
context 'when filter is a "string nil"' do
3143
before do
3244
params[:filter] = { first_name: 'nil' }
@@ -137,6 +149,23 @@
137149
params[:filter] = { name: 'Stephen' }
138150
expect(scope.resolve.map(&:id)).to eq([author1.id])
139151
end
152+
153+
context 'when accessing calling context' do
154+
before do
155+
resource_class.class_eval do
156+
default_filter :first_name do |scope, ctx|
157+
scope.where(id: ctx.runtime_id)
158+
end
159+
end
160+
end
161+
162+
it 'works' do
163+
ctx = double(runtime_id: author3.id).as_null_object
164+
JsonapiCompliable.with_context(ctx, {}) do
165+
expect(scope.resolve.map(&:id)).to eq([author3.id])
166+
end
167+
end
168+
end
140169
end
141170

142171
context 'when the filter is guarded' do

spec/pagination_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,22 @@
5252
it 'uses the custom pagination function' do
5353
expect(scope.resolve).to eq([])
5454
end
55+
56+
context 'and it accesses runtime context' do
57+
before do
58+
resource_class.class_eval do
59+
paginate do |scope, page, per_page, ctx|
60+
scope.limit(ctx.runtime_limit)
61+
end
62+
end
63+
end
64+
65+
it 'works' do
66+
ctx = double(runtime_limit: 2).as_null_object
67+
JsonapiCompliable.with_context(ctx, {}) do
68+
expect(scope.resolve.length).to eq(2)
69+
end
70+
end
71+
end
5572
end
5673
end

spec/scope_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
RSpec.describe JsonapiCompliable::Scope do
44
let(:object) { double.as_null_object }
5-
let(:resource) { double(type: :authors, default_page_size: 1).as_null_object }
65
let(:query_hash) { JsonapiCompliable::Query.default_hash }
76
let(:query) { double(to_hash: { authors: query_hash }) }
87
let(:instance) { described_class.new(object, resource, query) }
98

9+
let(:resource) do
10+
dbl = double type: :authors,
11+
default_page_size: 1,
12+
pagination: nil
13+
dbl.as_null_object
14+
end
15+
1016
describe '#resolve' do
1117
before do
1218
allow(query).to receive(:zero_results?) { false }

0 commit comments

Comments
 (0)