graphiti 1.0.alpha.18 → 1.0.alpha.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a57e6a62b24c36177cc2d7191754080204f43c3
4
- data.tar.gz: 28df77df0640febe4fa4bab38ecb9f51ee0f79f6
3
+ metadata.gz: 87db44b8b56a2b6341dd62b0d1ef7bdf37703127
4
+ data.tar.gz: 934774ad413a6ac695b612253249620efc0f7c9b
5
5
  SHA512:
6
- metadata.gz: 828cbf88441e63d92a056296751dc9a87ccb6dd4932946824f44ccef48ef0b828c498e0acbdc4751e89858188d4b13951d781d964d006ca8385daa343217c29f
7
- data.tar.gz: 2134f9e3dcfb4209179f9c074c17b379af68b00b0182ef7a9d854644b62328ea6d5edc45925d7bf0783b833e0fd5c48166baf29c181b388f9f0442672486ecb5
6
+ metadata.gz: 51ca1feec8cc701fd3786449d747f5ea44f72fd4e533fcb598793f74dc550e87aaa39a53eb4144e623653503a690a25d9ce2bf84b1bae253a66d92e5d84ab2fb
7
+ data.tar.gz: bf9acf3ecc4b5be6db1bc9d3e46c3591b59d48391bfa941fedf3c525418e8a8d393d91fee4ba9745e25a2fda1d92fb4499f500be323a55524a8c5cee2e72b9d8
@@ -9,6 +9,6 @@ class ApplicationResource < Graphiti::Resource
9
9
  # Subclasses can still override this default.
10
10
  <%- end -%>
11
11
  self.abstract_class = true
12
- self.adapter = Graphiti::Adapters::ActiveRecord::Base
12
+ self.adapter = Graphiti::Adapters::ActiveRecord
13
13
  self.endpoint_namespace = '<%= api_namespace %>'
14
14
  end
@@ -2,7 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  RSpec.describe "<%= type %>#create", type: :request do
4
4
  subject(:make_request) do
5
- jsonapi_post "/<%= api_namespace %>/v1/<%= type %>", payload
5
+ jsonapi_post "<%= api_namespace %>/<%= type %>", payload
6
6
  end
7
7
 
8
8
  describe 'basic create' do
@@ -2,7 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  RSpec.describe "<%= type %>#destroy", type: :request do
4
4
  subject(:make_request) do
5
- jsonapi_delete "/<%= api_namespace %>/v1/<%= type %>/#{<%= var %>.id}"
5
+ jsonapi_delete "<%= api_namespace %>/<%= type %>/#{<%= var %>.id}"
6
6
  end
7
7
 
8
8
  describe 'basic destroy' do
@@ -4,7 +4,7 @@ RSpec.describe "<%= type %>#index", type: :request do
4
4
  let(:params) { {} }
5
5
 
6
6
  subject(:make_request) do
7
- jsonapi_get "/<%= api_namespace %>/v1/<%= type %>", params: params
7
+ jsonapi_get "<%= api_namespace %>/<%= type %>", params: params
8
8
  end
9
9
 
10
10
  describe 'basic fetch' do
@@ -4,7 +4,7 @@ RSpec.describe "<%= type %>#show", type: :request do
4
4
  let(:params) { {} }
5
5
 
6
6
  subject(:make_request) do
7
- jsonapi_get "/<%= api_namespace %>/v1/<%= type %>/#{<%= var %>.id}", params: params
7
+ jsonapi_get "<%= api_namespace %>/<%= type %>/#{<%= var %>.id}", params: params
8
8
  end
9
9
 
10
10
  describe 'basic fetch' do
@@ -2,7 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  RSpec.describe "<%= type %>#update", type: :request do
4
4
  subject(:make_request) do
5
- jsonapi_put "/<%= api_namespace %>/v1/<%= type %>/#{<%= var %>.id}", payload
5
+ jsonapi_put "<%= api_namespace %>/<%= type %>/#{<%= var %>.id}", payload
6
6
  end
7
7
 
8
8
  describe 'basic update' do
@@ -469,7 +469,7 @@ module Graphiti
469
469
 
470
470
  def activerecord_adapter
471
471
  @activerecord_adapter ||=
472
- ::Graphiti::Adapters::ActiveRecord::Base.new(resource)
472
+ ::Graphiti::Adapters::ActiveRecord.new(resource)
473
473
  end
474
474
 
475
475
  def activerecord_associate?(parent, child, association_name)
@@ -1,6 +1,275 @@
1
- require 'graphiti/adapters/active_record/base'
2
- require 'graphiti/adapters/active_record/inferrence'
3
- require 'graphiti/adapters/active_record/has_many_sideload'
4
- require 'graphiti/adapters/active_record/belongs_to_sideload'
5
- require 'graphiti/adapters/active_record/has_one_sideload'
6
- require 'graphiti/adapters/active_record/many_to_many_sideload'
1
+ module Graphiti
2
+ module Adapters
3
+ class ActiveRecord < ::Graphiti::Adapters::Abstract
4
+ require 'graphiti/adapters/active_record/inferrence'
5
+ require 'graphiti/adapters/active_record/has_many_sideload'
6
+ require 'graphiti/adapters/active_record/belongs_to_sideload'
7
+ require 'graphiti/adapters/active_record/has_one_sideload'
8
+ require 'graphiti/adapters/active_record/many_to_many_sideload'
9
+
10
+ def self.sideloading_classes
11
+ {
12
+ has_many: Graphiti::Adapters::ActiveRecord::HasManySideload,
13
+ has_one: Graphiti::Adapters::ActiveRecord::HasOneSideload,
14
+ belongs_to: Graphiti::Adapters::ActiveRecord::BelongsToSideload,
15
+ many_to_many: Graphiti::Adapters::ActiveRecord::ManyToManySideload
16
+ }
17
+ end
18
+
19
+ def filter_eq(scope, attribute, value)
20
+ scope.where(attribute => value)
21
+ end
22
+ alias :filter_integer_eq :filter_eq
23
+ alias :filter_float_eq :filter_eq
24
+ alias :filter_big_decimal_eq :filter_eq
25
+ alias :filter_date_eq :filter_eq
26
+ alias :filter_boolean_eq :filter_eq
27
+
28
+ def filter_not_eq(scope, attribute, value)
29
+ scope.where.not(attribute => value)
30
+ end
31
+ alias :filter_integer_not_eq :filter_not_eq
32
+ alias :filter_float_not_eq :filter_not_eq
33
+ alias :filter_big_decimal_not_eq :filter_not_eq
34
+ alias :filter_date_not_eq :filter_not_eq
35
+ alias :filter_boolean_not_eq :filter_not_eq
36
+
37
+ def filter_string_eq(scope, attribute, value, is_not: false)
38
+ column = scope.klass.arel_table[attribute]
39
+ clause = column.lower.eq_any(value.map(&:downcase))
40
+ is_not ? scope.where.not(clause) : scope.where(clause)
41
+ end
42
+
43
+ def filter_string_eql(scope, attribute, value, is_not: false)
44
+ clause = { attribute => value }
45
+ is_not ? scope.where.not(clause) : scope.where(clause)
46
+ end
47
+
48
+ def filter_string_not_eq(scope, attribute, value)
49
+ filter_string_eq(scope, attribute, value, is_not: true)
50
+ end
51
+
52
+ def filter_string_not_eql(scope, attribute, value)
53
+ filter_string_eql(scope, attribute, value, is_not: true)
54
+ end
55
+
56
+ def filter_string_prefix(scope, attribute, value, is_not: false)
57
+ column = scope.klass.arel_table[attribute]
58
+ map = value.map { |v| "#{v}%" }
59
+ clause = column.lower.matches_any(map)
60
+ is_not ? scope.where.not(clause) : scope.where(clause)
61
+ end
62
+
63
+ def filter_string_not_prefix(scope, attribute, value)
64
+ filter_string_prefix(scope, attribute, value, is_not: true)
65
+ end
66
+
67
+ def filter_string_suffix(scope, attribute, value, is_not: false)
68
+ column = scope.klass.arel_table[attribute]
69
+ map = value.map { |v| "%#{v}" }
70
+ clause = column.lower.matches_any(map)
71
+ is_not ? scope.where.not(clause) : scope.where(clause)
72
+ end
73
+
74
+ def filter_string_not_suffix(scope, attribute, value)
75
+ filter_string_suffix(scope, attribute, value, is_not: true)
76
+ end
77
+
78
+ def filter_string_match(scope, attribute, value, is_not: false)
79
+ column = scope.klass.arel_table[attribute]
80
+ map = value.map { |v| "%#{v.downcase}%" }
81
+ clause = column.lower.matches_any(map)
82
+ is_not ? scope.where.not(clause) : scope.where(clause)
83
+ end
84
+
85
+ def filter_string_not_match(scope, attribute, value)
86
+ filter_string_match(scope, attribute, value, is_not: true)
87
+ end
88
+
89
+ def filter_gt(scope, attribute, value)
90
+ column = scope.klass.arel_table[attribute]
91
+ scope.where(column.gt_any(value))
92
+ end
93
+ alias :filter_integer_gt :filter_gt
94
+ alias :filter_float_gt :filter_gt
95
+ alias :filter_big_decimal_gt :filter_gt
96
+ alias :filter_datetime_gt :filter_gt
97
+ alias :filter_date_gt :filter_gt
98
+
99
+ def filter_gte(scope, attribute, value)
100
+ column = scope.klass.arel_table[attribute]
101
+ scope.where(column.gteq_any(value))
102
+ end
103
+ alias :filter_integer_gte :filter_gte
104
+ alias :filter_float_gte :filter_gte
105
+ alias :filter_big_decimal_gte :filter_gte
106
+ alias :filter_datetime_gte :filter_gte
107
+ alias :filter_date_gte :filter_gte
108
+
109
+ def filter_lt(scope, attribute, value)
110
+ column = scope.klass.arel_table[attribute]
111
+ scope.where(column.lt_any(value))
112
+ end
113
+ alias :filter_integer_lt :filter_lt
114
+ alias :filter_float_lt :filter_lt
115
+ alias :filter_big_decimal_lt :filter_lt
116
+ alias :filter_datetime_lt :filter_lt
117
+ alias :filter_date_lt :filter_lt
118
+
119
+ def filter_lte(scope, attribute, value)
120
+ column = scope.klass.arel_table[attribute]
121
+ scope.where(column.lteq_any(value))
122
+ end
123
+ alias :filter_integer_lte :filter_lte
124
+ alias :filter_float_lte :filter_lte
125
+ alias :filter_big_decimal_lte :filter_lte
126
+ alias :filter_date_lte :filter_lte
127
+
128
+ # Ensure fractional seconds don't matter
129
+ def filter_datetime_eq(scope, attribute, value, is_not: false)
130
+ ranges = value.map { |v| (v..v+1.second-0.00000001) }
131
+ clause = { attribute => ranges }
132
+ is_not ? scope.where.not(clause) : scope.where(clause)
133
+ end
134
+
135
+ def filter_datetime_not_eq(scope, attribute, value)
136
+ filter_datetime_eq(scope, attribute, value, is_not: true)
137
+ end
138
+
139
+ def filter_datetime_lte(scope, attribute, value)
140
+ value = value.map { |v| v + 1.second-0.00000001 }
141
+ column = scope.klass.arel_table[attribute]
142
+ scope.where(column.lteq_any(value))
143
+ end
144
+
145
+ def base_scope(model)
146
+ model.all
147
+ end
148
+
149
+ # (see Adapters::Abstract#order)
150
+ def order(scope, attribute, direction)
151
+ scope.order(attribute => direction)
152
+ end
153
+
154
+ # (see Adapters::Abstract#paginate)
155
+ def paginate(scope, current_page, per_page)
156
+ scope.page(current_page).per(per_page)
157
+ end
158
+
159
+ # (see Adapters::Abstract#count)
160
+ def count(scope, attr)
161
+ if attr.to_sym == :total
162
+ scope.distinct.count
163
+ else
164
+ scope.distinct.count(attr)
165
+ end
166
+ end
167
+
168
+ # (see Adapters::Abstract#average)
169
+ def average(scope, attr)
170
+ scope.average(attr).to_f
171
+ end
172
+
173
+ # (see Adapters::Abstract#sum)
174
+ def sum(scope, attr)
175
+ scope.sum(attr)
176
+ end
177
+
178
+ # (see Adapters::Abstract#maximum)
179
+ def maximum(scope, attr)
180
+ scope.maximum(attr)
181
+ end
182
+
183
+ # (see Adapters::Abstract#minimum)
184
+ def minimum(scope, attr)
185
+ scope.minimum(attr)
186
+ end
187
+
188
+ # (see Adapters::Abstract#resolve)
189
+ def resolve(scope)
190
+ scope.to_a
191
+ end
192
+
193
+ # Run this write request within an ActiveRecord transaction
194
+ # @param [Class] model_class The ActiveRecord class we are saving
195
+ # @return Result of yield
196
+ # @see Adapters::Abstract#transaction
197
+ def transaction(model_class)
198
+ model_class.transaction do
199
+ yield
200
+ end
201
+ end
202
+
203
+ def belongs_to_many_filter(sideload, scope, value)
204
+ scope
205
+ .includes(sideload.through_relationship_name)
206
+ .where(sideload.through_table_name => {
207
+ sideload.true_foreign_key => value
208
+ })
209
+ end
210
+
211
+ def associate_all(parent, children, association_name, association_type)
212
+ if activerecord_associate?(parent, children[0], association_name)
213
+ association = parent.association(association_name)
214
+ association.loaded!
215
+
216
+ children.each do |child|
217
+ if association_type == :many_to_many &&
218
+ !parent.send(association_name).exists?(child.id) &&
219
+ [:create, :update].include?(Graphiti.context[:namespace])
220
+ parent.send(association_name) << child
221
+ else
222
+ target = association.instance_variable_get(:@target)
223
+ target |= [child]
224
+ association.instance_variable_set(:@target, target)
225
+ end
226
+ end
227
+ else
228
+ super
229
+ end
230
+ end
231
+
232
+ def associate(parent, child, association_name, association_type)
233
+ if activerecord_associate?(parent, child, association_name)
234
+ association = parent.association(association_name)
235
+ association.loaded!
236
+ association.instance_variable_set(:@target, child)
237
+ else
238
+ super
239
+ end
240
+ end
241
+
242
+ # When a has_and_belongs_to_many relationship, we don't have a foreign
243
+ # key that can be null'd. Instead, go through the ActiveRecord API.
244
+ # @see Adapters::Abstract#disassociate
245
+ def disassociate(parent, child, association_name, association_type)
246
+ if association_type == :many_to_many
247
+ parent.send(association_name).delete(child)
248
+ else
249
+ # Nothing to do here, happened when we merged foreign key
250
+ end
251
+ end
252
+
253
+ # (see Adapters::Abstract#create)
254
+ def create(model_class, create_params)
255
+ instance = model_class.new(create_params)
256
+ instance.save
257
+ instance
258
+ end
259
+
260
+ # (see Adapters::Abstract#update)
261
+ def update(model_class, update_params)
262
+ instance = model_class.find(update_params.delete(:id))
263
+ instance.update_attributes(update_params)
264
+ instance
265
+ end
266
+
267
+ # (see Adapters::Abstract#destroy)
268
+ def destroy(model_class, id)
269
+ instance = model_class.find(id)
270
+ instance.destroy
271
+ instance
272
+ end
273
+ end
274
+ end
275
+ end
@@ -1,17 +1,11 @@
1
- module Graphiti
2
- module Adapters
3
- module ActiveRecord
4
- class BelongsToSideload < Sideload::BelongsTo
5
- include Inferrence
1
+ class Graphiti::Adapters::ActiveRecord::BelongsToSideload < Graphiti::Sideload::BelongsTo
2
+ include Graphiti::Adapters::ActiveRecord::Inferrence
6
3
 
7
- def default_base_scope
8
- resource_class.model.all
9
- end
4
+ def default_base_scope
5
+ resource_class.model.all
6
+ end
10
7
 
11
- def scope(parent_ids)
12
- base_scope.where(primary_key => parent_ids)
13
- end
14
- end
15
- end
8
+ def scope(parent_ids)
9
+ base_scope.where(primary_key => parent_ids)
16
10
  end
17
11
  end
@@ -1,17 +1,11 @@
1
- module Graphiti
2
- module Adapters
3
- module ActiveRecord # todo change
4
- class HasManySideload < Sideload::HasMany
5
- include Inferrence
1
+ class Graphiti::Adapters::ActiveRecord::HasManySideload < Graphiti::Sideload::HasMany
2
+ include Graphiti::Adapters::ActiveRecord::Inferrence
6
3
 
7
- def default_base_scope
8
- resource_class.model.all
9
- end
4
+ def default_base_scope
5
+ resource_class.model.all
6
+ end
10
7
 
11
- def scope(parent_ids)
12
- base_scope.where(foreign_key => parent_ids)
13
- end
14
- end
15
- end
8
+ def scope(parent_ids)
9
+ base_scope.where(foreign_key => parent_ids)
16
10
  end
17
11
  end
@@ -1,17 +1,11 @@
1
- module Graphiti
2
- module Adapters
3
- module ActiveRecord
4
- class HasOneSideload < Sideload::HasOne
5
- include Inferrence
1
+ class Graphiti::Adapters::ActiveRecord::HasOneSideload < Graphiti::Sideload::HasOne
2
+ include Graphiti::Adapters::ActiveRecord::Inferrence
6
3
 
7
- def default_base_scope
8
- resource_class.model.all
9
- end
4
+ def default_base_scope
5
+ resource_class.model.all
6
+ end
10
7
 
11
- def scope(parent_ids)
12
- base_scope.where(foreign_key => parent_ids)
13
- end
14
- end
15
- end
8
+ def scope(parent_ids)
9
+ base_scope.where(foreign_key => parent_ids)
16
10
  end
17
11
  end
@@ -1,19 +1,13 @@
1
- module Graphiti
2
- module Adapters
3
- module ActiveRecord
4
- module Inferrence
5
- # If going AR to AR, use AR introspection
6
- # If going AR to PORO, fall back to normal inferrence
7
- def infer_foreign_key
8
- parent_model = parent_resource_class.model
9
- reflection = parent_model.reflections[association_name.to_s]
10
- if reflection
11
- reflection.foreign_key.to_sym
12
- else
13
- super
14
- end
15
- end
16
- end
1
+ module Graphiti::Adapters::ActiveRecord::Inferrence
2
+ # If going AR to AR, use AR introspection
3
+ # If going AR to PORO, fall back to normal inferrence
4
+ def infer_foreign_key
5
+ parent_model = parent_resource_class.model
6
+ reflection = parent_model.reflections[association_name.to_s]
7
+ if reflection
8
+ reflection.foreign_key.to_sym
9
+ else
10
+ super
17
11
  end
18
12
  end
19
13
  end
@@ -1,23 +1,17 @@
1
- module Graphiti
2
- module Adapters
3
- module ActiveRecord
4
- class ManyToManySideload < Sideload::ManyToMany
5
- def through_table_name
6
- @through_table_name ||= parent_resource_class.model
7
- .reflections[through.to_s].klass.table_name
8
- end
1
+ class Graphiti::Adapters::ActiveRecord::ManyToManySideload < Graphiti::Sideload::ManyToMany
2
+ def through_table_name
3
+ @through_table_name ||= parent_resource_class.model
4
+ .reflections[through.to_s].klass.table_name
5
+ end
9
6
 
10
- def through_relationship_name
11
- foreign_key.keys.first
12
- end
7
+ def through_relationship_name
8
+ foreign_key.keys.first
9
+ end
13
10
 
14
- def infer_foreign_key
15
- parent_model = parent_resource_class.model
16
- key = parent_model.reflections[name.to_s].options[:through]
17
- value = parent_model.reflections[key.to_s].foreign_key.to_sym
18
- { key => value }
19
- end
20
- end
21
- end
11
+ def infer_foreign_key
12
+ parent_model = parent_resource_class.model
13
+ key = parent_model.reflections[name.to_s].options[:through]
14
+ value = parent_model.reflections[key.to_s].foreign_key.to_sym
15
+ { key => value }
22
16
  end
23
17
  end
@@ -1,3 +1,3 @@
1
1
  module Graphiti
2
- VERSION = "1.0.alpha.18"
2
+ VERSION = "1.0.alpha.19"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphiti
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.alpha.18
4
+ version: 1.0.alpha.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
@@ -236,7 +236,6 @@ files:
236
236
  - lib/graphiti.rb
237
237
  - lib/graphiti/adapters/abstract.rb
238
238
  - lib/graphiti/adapters/active_record.rb
239
- - lib/graphiti/adapters/active_record/base.rb
240
239
  - lib/graphiti/adapters/active_record/belongs_to_sideload.rb
241
240
  - lib/graphiti/adapters/active_record/has_many_sideload.rb
242
241
  - lib/graphiti/adapters/active_record/has_one_sideload.rb
@@ -1,271 +0,0 @@
1
- module Graphiti
2
- module Adapters
3
- module ActiveRecord
4
- class Base < ::Graphiti::Adapters::Abstract
5
- def filter_eq(scope, attribute, value)
6
- scope.where(attribute => value)
7
- end
8
- alias :filter_integer_eq :filter_eq
9
- alias :filter_float_eq :filter_eq
10
- alias :filter_big_decimal_eq :filter_eq
11
- alias :filter_date_eq :filter_eq
12
- alias :filter_boolean_eq :filter_eq
13
-
14
- def filter_not_eq(scope, attribute, value)
15
- scope.where.not(attribute => value)
16
- end
17
- alias :filter_integer_not_eq :filter_not_eq
18
- alias :filter_float_not_eq :filter_not_eq
19
- alias :filter_big_decimal_not_eq :filter_not_eq
20
- alias :filter_date_not_eq :filter_not_eq
21
- alias :filter_boolean_not_eq :filter_not_eq
22
-
23
- def filter_string_eq(scope, attribute, value, is_not: false)
24
- column = scope.klass.arel_table[attribute]
25
- clause = column.lower.eq_any(value.map(&:downcase))
26
- is_not ? scope.where.not(clause) : scope.where(clause)
27
- end
28
-
29
- def filter_string_eql(scope, attribute, value, is_not: false)
30
- clause = { attribute => value }
31
- is_not ? scope.where.not(clause) : scope.where(clause)
32
- end
33
-
34
- def filter_string_not_eq(scope, attribute, value)
35
- filter_string_eq(scope, attribute, value, is_not: true)
36
- end
37
-
38
- def filter_string_not_eql(scope, attribute, value)
39
- filter_string_eql(scope, attribute, value, is_not: true)
40
- end
41
-
42
- def filter_string_prefix(scope, attribute, value, is_not: false)
43
- column = scope.klass.arel_table[attribute]
44
- map = value.map { |v| "#{v}%" }
45
- clause = column.lower.matches_any(map)
46
- is_not ? scope.where.not(clause) : scope.where(clause)
47
- end
48
-
49
- def filter_string_not_prefix(scope, attribute, value)
50
- filter_string_prefix(scope, attribute, value, is_not: true)
51
- end
52
-
53
- def filter_string_suffix(scope, attribute, value, is_not: false)
54
- column = scope.klass.arel_table[attribute]
55
- map = value.map { |v| "%#{v}" }
56
- clause = column.lower.matches_any(map)
57
- is_not ? scope.where.not(clause) : scope.where(clause)
58
- end
59
-
60
- def filter_string_not_suffix(scope, attribute, value)
61
- filter_string_suffix(scope, attribute, value, is_not: true)
62
- end
63
-
64
- def filter_string_match(scope, attribute, value, is_not: false)
65
- column = scope.klass.arel_table[attribute]
66
- map = value.map { |v| "%#{v.downcase}%" }
67
- clause = column.lower.matches_any(map)
68
- is_not ? scope.where.not(clause) : scope.where(clause)
69
- end
70
-
71
- def filter_string_not_match(scope, attribute, value)
72
- filter_string_match(scope, attribute, value, is_not: true)
73
- end
74
-
75
- def filter_gt(scope, attribute, value)
76
- column = scope.klass.arel_table[attribute]
77
- scope.where(column.gt_any(value))
78
- end
79
- alias :filter_integer_gt :filter_gt
80
- alias :filter_float_gt :filter_gt
81
- alias :filter_big_decimal_gt :filter_gt
82
- alias :filter_datetime_gt :filter_gt
83
- alias :filter_date_gt :filter_gt
84
-
85
- def filter_gte(scope, attribute, value)
86
- column = scope.klass.arel_table[attribute]
87
- scope.where(column.gteq_any(value))
88
- end
89
- alias :filter_integer_gte :filter_gte
90
- alias :filter_float_gte :filter_gte
91
- alias :filter_big_decimal_gte :filter_gte
92
- alias :filter_datetime_gte :filter_gte
93
- alias :filter_date_gte :filter_gte
94
-
95
- def filter_lt(scope, attribute, value)
96
- column = scope.klass.arel_table[attribute]
97
- scope.where(column.lt_any(value))
98
- end
99
- alias :filter_integer_lt :filter_lt
100
- alias :filter_float_lt :filter_lt
101
- alias :filter_big_decimal_lt :filter_lt
102
- alias :filter_datetime_lt :filter_lt
103
- alias :filter_date_lt :filter_lt
104
-
105
- def filter_lte(scope, attribute, value)
106
- column = scope.klass.arel_table[attribute]
107
- scope.where(column.lteq_any(value))
108
- end
109
- alias :filter_integer_lte :filter_lte
110
- alias :filter_float_lte :filter_lte
111
- alias :filter_big_decimal_lte :filter_lte
112
- alias :filter_date_lte :filter_lte
113
-
114
- # Ensure fractional seconds don't matter
115
- def filter_datetime_eq(scope, attribute, value, is_not: false)
116
- ranges = value.map { |v| (v..v+1.second-0.00000001) }
117
- clause = { attribute => ranges }
118
- is_not ? scope.where.not(clause) : scope.where(clause)
119
- end
120
-
121
- def filter_datetime_not_eq(scope, attribute, value)
122
- filter_datetime_eq(scope, attribute, value, is_not: true)
123
- end
124
-
125
- def filter_datetime_lte(scope, attribute, value)
126
- value = value.map { |v| v + 1.second-0.00000001 }
127
- column = scope.klass.arel_table[attribute]
128
- scope.where(column.lteq_any(value))
129
- end
130
-
131
- def base_scope(model)
132
- model.all
133
- end
134
-
135
- # (see Adapters::Abstract#order)
136
- def order(scope, attribute, direction)
137
- scope.order(attribute => direction)
138
- end
139
-
140
- # (see Adapters::Abstract#paginate)
141
- def paginate(scope, current_page, per_page)
142
- scope.page(current_page).per(per_page)
143
- end
144
-
145
- # (see Adapters::Abstract#count)
146
- def count(scope, attr)
147
- if attr.to_sym == :total
148
- scope.distinct.count
149
- else
150
- scope.distinct.count(attr)
151
- end
152
- end
153
-
154
- # (see Adapters::Abstract#average)
155
- def average(scope, attr)
156
- scope.average(attr).to_f
157
- end
158
-
159
- # (see Adapters::Abstract#sum)
160
- def sum(scope, attr)
161
- scope.sum(attr)
162
- end
163
-
164
- # (see Adapters::Abstract#maximum)
165
- def maximum(scope, attr)
166
- scope.maximum(attr)
167
- end
168
-
169
- # (see Adapters::Abstract#minimum)
170
- def minimum(scope, attr)
171
- scope.minimum(attr)
172
- end
173
-
174
- # (see Adapters::Abstract#resolve)
175
- def resolve(scope)
176
- scope.to_a
177
- end
178
-
179
- # Run this write request within an ActiveRecord transaction
180
- # @param [Class] model_class The ActiveRecord class we are saving
181
- # @return Result of yield
182
- # @see Adapters::Abstract#transaction
183
- def transaction(model_class)
184
- model_class.transaction do
185
- yield
186
- end
187
- end
188
-
189
- def self.sideloading_classes
190
- {
191
- has_many: HasManySideload,
192
- has_one: HasOneSideload,
193
- belongs_to: BelongsToSideload,
194
- many_to_many: ManyToManySideload
195
- }
196
- end
197
-
198
- def belongs_to_many_filter(sideload, scope, value)
199
- scope
200
- .includes(sideload.through_relationship_name)
201
- .where(sideload.through_table_name => {
202
- sideload.true_foreign_key => value
203
- })
204
- end
205
-
206
- def associate_all(parent, children, association_name, association_type)
207
- if activerecord_associate?(parent, children[0], association_name)
208
- association = parent.association(association_name)
209
- association.loaded!
210
-
211
- children.each do |child|
212
- if association_type == :many_to_many &&
213
- !parent.send(association_name).exists?(child.id) &&
214
- [:create, :update].include?(Graphiti.context[:namespace])
215
- parent.send(association_name) << child
216
- else
217
- target = association.instance_variable_get(:@target)
218
- target |= [child]
219
- association.instance_variable_set(:@target, target)
220
- end
221
- end
222
- else
223
- super
224
- end
225
- end
226
-
227
- def associate(parent, child, association_name, association_type)
228
- if activerecord_associate?(parent, child, association_name)
229
- association = parent.association(association_name)
230
- association.loaded!
231
- association.instance_variable_set(:@target, child)
232
- else
233
- super
234
- end
235
- end
236
-
237
- # When a has_and_belongs_to_many relationship, we don't have a foreign
238
- # key that can be null'd. Instead, go through the ActiveRecord API.
239
- # @see Adapters::Abstract#disassociate
240
- def disassociate(parent, child, association_name, association_type)
241
- if association_type == :many_to_many
242
- parent.send(association_name).delete(child)
243
- else
244
- # Nothing to do here, happened when we merged foreign key
245
- end
246
- end
247
-
248
- # (see Adapters::Abstract#create)
249
- def create(model_class, create_params)
250
- instance = model_class.new(create_params)
251
- instance.save
252
- instance
253
- end
254
-
255
- # (see Adapters::Abstract#update)
256
- def update(model_class, update_params)
257
- instance = model_class.find(update_params.delete(:id))
258
- instance.update_attributes(update_params)
259
- instance
260
- end
261
-
262
- # (see Adapters::Abstract#destroy)
263
- def destroy(model_class, id)
264
- instance = model_class.find(id)
265
- instance.destroy
266
- instance
267
- end
268
- end
269
- end
270
- end
271
- end