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

Sign up to get free protection for your applications and to get access to all the features.
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