effective_resources 2.1.4 → 2.2.0
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 +4 -4
- data/app/models/concerns/acts_as_purchasable_wizard.rb +1 -0
- data/app/models/effective/resources/forms.rb +4 -4
- data/app/models/effective/resources/relation.rb +238 -169
- data/app/models/effective/resources/sql.rb +9 -0
- data/lib/effective_resources/version.rb +1 -1
- data/lib/effective_resources.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 570e952fca070a0e231d90c8f959a80055d6a32e0b1ec51e93ae9c88d90fd44a
|
4
|
+
data.tar.gz: c7b247bfb4f12f6368405ac21f0a8591dc5e000d3f4a02c2daf728489d171128
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb7ee9c3d1be22a10ad2b2d2b24e21a4af3bb084f8bdf07b484f67922ea68553bb31410562029e6b762076eec1bd6bf9eb510734c3c2c35f4c31d768479443a9
|
7
|
+
data.tar.gz: 1e905d78f87ddac0bfb423ad153c1066f9925739bf7f454296b9554c6c4ef6ff4a147b125f98b1a0cddeab61bfaa7e2f710d0121e7376ca7f03b62e2e7b9a09c
|
@@ -73,13 +73,13 @@ module Effective
|
|
73
73
|
{ as: :string }
|
74
74
|
else
|
75
75
|
if res.klass.unscoped.respond_to?(:datatables_scope)
|
76
|
-
{ collection: res.klass.datatables_scope.map { |obj| [obj.to_s, obj.
|
76
|
+
{ collection: res.klass.datatables_scope.map { |obj| [obj.to_s, obj.id] } }
|
77
77
|
elsif res.klass.unscoped.respond_to?(:datatables_filter)
|
78
|
-
{ collection: res.klass.datatables_filter.map { |obj| [obj.to_s, obj.
|
78
|
+
{ collection: res.klass.datatables_filter.map { |obj| [obj.to_s, obj.id] } }
|
79
79
|
elsif res.klass.unscoped.respond_to?(:sorted)
|
80
|
-
{ collection: res.klass.sorted.map { |obj| [obj.to_s, obj.
|
80
|
+
{ collection: res.klass.sorted.map { |obj| [obj.to_s, obj.id] } }
|
81
81
|
else
|
82
|
-
{ collection: res.klass.all.map { |obj| [obj.to_s, obj.
|
82
|
+
{ collection: res.klass.all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[0] <=> y[0] } }
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -65,125 +65,274 @@ module Effective
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
def search(name, value, as: nil,
|
68
|
+
def search(name, value, as: nil, column: nil, operation: nil)
|
69
69
|
raise 'expected relation to be present' unless relation
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
sql_as = (as || sql_type(name))
|
72
|
+
sql_column = (column || sql_column(name))
|
73
|
+
sql_operation = (operation || sql_operation(name, as: sql_as)).to_sym
|
74
74
|
|
75
75
|
if ['SUM(', 'COUNT(', 'MAX(', 'MIN(', 'AVG('].any? { |str| sql_column.to_s.include?(str) }
|
76
76
|
return relation.having("#{sql_column} = ?", value)
|
77
77
|
end
|
78
78
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
return relation.where(is_null(sql_column))
|
79
|
+
case sql_as
|
80
|
+
when :belongs_to, :belongs_to_polymorphic, :has_and_belongs_to_many, :has_many, :has_one
|
81
|
+
search_associated(name, value, as: sql_as, operation: sql_operation)
|
82
|
+
else
|
83
|
+
return relation.where(is_null(sql_column)) if value.to_s == 'nil'
|
84
|
+
search_attribute(name, value, as: sql_as, operation: sql_operation)
|
86
85
|
end
|
86
|
+
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
88
|
+
def search_associated(name, value, as:, operation:)
|
89
|
+
reflection = associated(name)
|
90
|
+
raise("expected to find #{relation.klass.name} #{name} reflection") unless reflection
|
91
|
+
raise("expected association operation") unless [:eq, :matches, :does_not_match, :sql].include?(operation)
|
92
|
+
|
93
|
+
# Parse values
|
94
|
+
value_ids = value.kind_of?(Array) ? value : (value.to_s.split(/,|\s|\|/) - [nil, '', ' '])
|
95
|
+
value_sql = Arel.sql(value) if value.kind_of?(String)
|
96
|
+
|
97
|
+
# Foreign id and type
|
98
|
+
foreign_id = reflection.foreign_key
|
99
|
+
foreign_type = reflection.foreign_key.to_s.chomp('_id') + '_type'
|
100
|
+
|
101
|
+
# belongs_to polymorphic
|
102
|
+
retval = if as == :belongs_to_polymorphic
|
103
|
+
(type, id) = value.to_s.split('_')
|
104
|
+
|
105
|
+
if type.present? && id.present? # This was from a polymorphic select
|
106
|
+
case operation
|
107
|
+
when :eq
|
108
|
+
relation.where(foreign_type => type, foreign_id => id)
|
109
|
+
when :matches
|
110
|
+
relation.where(foreign_type => type, foreign_id => id)
|
111
|
+
when :does_not_match
|
112
|
+
relation.where.not(foreign_type => type, foreign_id => id)
|
113
|
+
when :sql
|
114
|
+
if (relation.where(value_sql).present? rescue :invalid) != :invalid
|
115
|
+
relation.where(value_sql)
|
116
|
+
else
|
117
|
+
relation
|
118
|
+
end
|
119
|
+
end
|
102
120
|
else # Maybe from a string field
|
103
|
-
|
121
|
+
associated = relation.none
|
104
122
|
|
105
|
-
relation.unscoped.distinct(
|
123
|
+
relation.unscoped.distinct(foreign_type).pluck(foreign_type).each do |klass_name|
|
106
124
|
next if klass_name.nil?
|
107
125
|
|
108
126
|
resource = Effective::Resource.new(klass_name)
|
109
127
|
next unless resource.klass.present?
|
110
128
|
|
111
|
-
|
129
|
+
associated = associated.or(relation.where(foreign_id => resource.search_any(value), foreign_type => klass_name))
|
112
130
|
end
|
113
131
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
.where(ActiveStorage::Blob.arel_table[:filename].matches("%#{term}%"))
|
128
|
-
when :boolean
|
129
|
-
relation.where("#{sql_column} = ?", term)
|
130
|
-
when :datetime, :date
|
131
|
-
end_at = (
|
132
|
-
case (value.to_s.scan(/(\d+)/).flatten).length
|
133
|
-
when 1 ; term.end_of_year # Year
|
134
|
-
when 2 ; term.end_of_month # Year-Month
|
135
|
-
when 3 ; term.end_of_day # Year-Month-Day
|
136
|
-
when 4 ; term.end_of_hour # Year-Month-Day Hour
|
137
|
-
when 5 ; term.end_of_minute # Year-Month-Day Hour-Minute
|
138
|
-
when 6 ; term + 1.second # Year-Month-Day Hour-Minute-Second
|
139
|
-
else term
|
132
|
+
case operation
|
133
|
+
when :eq
|
134
|
+
relation.where(id: associated.select(:id))
|
135
|
+
when :matches
|
136
|
+
relation.where(id: associated.select(:id))
|
137
|
+
when :does_not_match
|
138
|
+
relation.where.not(id: associated.select(:id))
|
139
|
+
when :sql
|
140
|
+
if (relation.where(value_sql).present? rescue :invalid) != :invalid
|
141
|
+
relation.where(value_sql)
|
142
|
+
else
|
143
|
+
relation
|
144
|
+
end
|
140
145
|
end
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
146
|
+
end
|
147
|
+
|
148
|
+
# belongs_to non-polymorphic
|
149
|
+
elsif as == :belongs_to
|
150
|
+
foreign_collection = reflection.klass.all
|
151
|
+
foreign_collection = reflection.klass.where(foreign_type => relation.klass.name) if reflection.klass.new.respond_to?(foreign_type)
|
152
|
+
|
153
|
+
case operation
|
154
|
+
when :eq
|
155
|
+
associated = foreign_collection.where(id: value_ids)
|
156
|
+
relation.where(foreign_id => associated.select(:id))
|
157
|
+
when :matches
|
158
|
+
associated = Resource.new(foreign_collection).search_any(value)
|
159
|
+
relation.where(foreign_id => associated.select(:id))
|
160
|
+
when :does_not_match
|
161
|
+
associated = Resource.new(foreign_collection).search_any(value)
|
162
|
+
relation.where.not(foreign_id => associated.select(:id))
|
163
|
+
when :sql
|
164
|
+
if (foreign_collection.where(value_sql).present? rescue :invalid) != :invalid
|
165
|
+
associated = foreign_collection.where(value_sql)
|
166
|
+
relation.where(foreign_id => associated.select(:id))
|
151
167
|
else
|
152
|
-
relation
|
168
|
+
relation
|
153
169
|
end
|
154
|
-
else
|
155
|
-
relation.where("#{sql_column} = ?", term)
|
156
170
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
171
|
+
|
172
|
+
# has_and_belongs_to_many
|
173
|
+
elsif as == :has_and_belongs_to_many
|
174
|
+
foreign_collection = reflection.source_reflection.klass.all
|
175
|
+
|
176
|
+
habtm = foreign_collection.klass.reflect_on_all_associations.find { |ass| ass.macro == :has_and_belongs_to_many && ass.join_table == reflection.join_table }
|
177
|
+
raise("expected a matching HABTM reflection") unless habtm
|
178
|
+
|
179
|
+
case operation
|
180
|
+
when :eq
|
181
|
+
associated = foreign_collection.where(id: value_ids)
|
182
|
+
relation.where(id: associated.joins(habtm.name).select(foreign_id))
|
183
|
+
when :matches
|
184
|
+
associated = Resource.new(foreign_collection).search_any(value)
|
185
|
+
relation.where(id: associated.joins(habtm.name).select(foreign_id))
|
186
|
+
when :does_not_match
|
187
|
+
associated = Resource.new(foreign_collection).search_any(value)
|
188
|
+
relation.where.not(id: associated.joins(habtm.name).select(foreign_id))
|
189
|
+
when :sql
|
190
|
+
if (foreign_collection.where(value_sql).present? rescue :invalid) != :invalid
|
191
|
+
associated = foreign_collection.where(value_sql)
|
192
|
+
relation.where(id: associated.joins(habtm.name).select(foreign_id))
|
161
193
|
else
|
162
|
-
relation
|
194
|
+
relation
|
163
195
|
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# has_many through
|
199
|
+
elsif reflection.options[:through].present?
|
200
|
+
reflected_klass = if reflection.source_reflection.options[:polymorphic]
|
201
|
+
reflection.klass
|
164
202
|
else
|
165
|
-
|
203
|
+
reflection.source_reflection.klass
|
166
204
|
end
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
relation.where("#{sql_column} = ?", term)
|
171
|
-
when :price
|
172
|
-
relation.where("#{sql_column} = ?", term)
|
173
|
-
when :string, :text, :email
|
174
|
-
if fuzzy
|
175
|
-
relation.where("#{sql_column} #{ilike} ?", "%#{term}%")
|
205
|
+
|
206
|
+
reflected_id = if reflection.source_reflection.macro == :belongs_to
|
207
|
+
reflection.source_reflection.foreign_key # to do check this
|
176
208
|
else
|
177
|
-
|
209
|
+
reflection.source_reflection.klass.primary_key # group_id
|
178
210
|
end
|
179
|
-
|
180
|
-
if
|
181
|
-
|
211
|
+
|
212
|
+
foreign_id = if reflection.through_reflection.macro == :belongs_to
|
213
|
+
reflection.through_reflection.klass.primary_key # to do check this
|
182
214
|
else
|
183
|
-
|
215
|
+
reflection.through_reflection.foreign_key # user_id
|
216
|
+
end
|
217
|
+
|
218
|
+
# Build the through collection
|
219
|
+
through = reflection.through_reflection.klass.all # group mates
|
220
|
+
|
221
|
+
if reflection.source_reflection.options[:polymorphic]
|
222
|
+
through = through.where(reflection.source_reflection.foreign_type => reflected_klass.name)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Search the associated class
|
226
|
+
case operation
|
227
|
+
when :eq
|
228
|
+
associated = through.where(reflected_id => value_ids)
|
229
|
+
relation.where(id: associated.select(foreign_id))
|
230
|
+
when :matches
|
231
|
+
reflected = Resource.new(reflected_klass).search_any(value)
|
232
|
+
associated = through.where(reflected_id => reflected)
|
233
|
+
relation.where(id: associated.select(foreign_id))
|
234
|
+
when :does_not_match
|
235
|
+
reflected = Resource.new(reflected_klass).search_any(value)
|
236
|
+
associated = through.where(reflected_id => reflected)
|
237
|
+
relation.where.not(id: associated.select(foreign_id))
|
238
|
+
when :sql
|
239
|
+
if (reflected_klass.where(value_sql).present? rescue :invalid) != :invalid
|
240
|
+
reflected = reflected_klass.where(value_sql)
|
241
|
+
associated = through.where(reflected_id => reflected)
|
242
|
+
relation.where(id: associated.select(foreign_id))
|
243
|
+
else
|
244
|
+
relation
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# has_many and has_one
|
249
|
+
elsif (as == :has_many || as == :has_one)
|
250
|
+
foreign_collection = reflection.klass.all
|
251
|
+
foreign_collection = reflection.klass.where(foreign_type => relation.klass.name) if reflection.klass.new.respond_to?(foreign_type)
|
252
|
+
|
253
|
+
case operation
|
254
|
+
when :eq
|
255
|
+
associated = foreign_collection.where(id: value_ids)
|
256
|
+
relation.where(id: associated.select(foreign_id))
|
257
|
+
when :matches
|
258
|
+
associated = Resource.new(foreign_collection).search_any(value)
|
259
|
+
relation.where(id: associated.select(foreign_id))
|
260
|
+
when :does_not_match
|
261
|
+
associated = Resource.new(foreign_collection).search_any(value)
|
262
|
+
relation.where.not(id: associated.select(foreign_id))
|
263
|
+
when :sql
|
264
|
+
if (foreign_collection.where(value_sql).present? rescue :invalid) != :invalid
|
265
|
+
associated = foreign_collection.where(value_sql)
|
266
|
+
relation.where(id: associated.select(foreign_id))
|
267
|
+
else
|
268
|
+
relation
|
269
|
+
end
|
184
270
|
end
|
185
|
-
|
186
|
-
|
271
|
+
end
|
272
|
+
|
273
|
+
retval || raise("unable to search associated #{as} #{operation} #{name} for #{value}")
|
274
|
+
end
|
275
|
+
|
276
|
+
def search_attribute(name, value, as:, operation:)
|
277
|
+
raise 'expected relation to be present' unless relation
|
278
|
+
|
279
|
+
attribute = relation.arel_table[name]
|
280
|
+
|
281
|
+
# Normalize the term.
|
282
|
+
# If you pass an email attribute it can return nil so we return the full value
|
283
|
+
term = Attribute.new(as).parse(value, name: name) || value
|
284
|
+
|
285
|
+
searched = case as
|
286
|
+
when :date, :datetime
|
287
|
+
if value.kind_of?(String)
|
288
|
+
end_at = (
|
289
|
+
case (value.to_s.scan(/(\d+)/).flatten).length
|
290
|
+
when 1 ; term.end_of_year # Year
|
291
|
+
when 2 ; term.end_of_month # Year-Month
|
292
|
+
when 3 ; term.end_of_day # Year-Month-Day
|
293
|
+
when 4 ; term.end_of_hour # Year-Month-Day Hour
|
294
|
+
when 5 ; term.end_of_minute # Year-Month-Day Hour-Minute
|
295
|
+
when 6 ; term + 1.second # Year-Month-Day Hour-Minute-Second
|
296
|
+
else term
|
297
|
+
end
|
298
|
+
)
|
299
|
+
|
300
|
+
relation.where(attribute.gteq(term)).where(attribute.lteq(end_at))
|
301
|
+
end
|
302
|
+
|
303
|
+
when :effective_obfuscation
|
304
|
+
term = Attribute.new(as, klass: (associated(name).try(:klass) || klass)).parse(value, name: name)
|
305
|
+
relation.where(attribute.eq((value == term ? 0 : term)))
|
306
|
+
|
307
|
+
when :effective_addresses
|
308
|
+
association = associated(name)
|
309
|
+
associated = Resource.new(association).search_any(value)
|
310
|
+
relation.where(id: associated.where(addressable_type: klass.name).select(:addressable_id))
|
311
|
+
|
312
|
+
when :effective_roles
|
313
|
+
relation.with_role(term)
|
314
|
+
|
315
|
+
when :time
|
316
|
+
timed = relation.where("EXTRACT(hour from #{sql_column}) = ?", term.utc.hour)
|
317
|
+
timed = timed.where("EXTRACT(minute from #{sql_column}) = ?", term.utc.min) if term.min > 0
|
318
|
+
timed
|
319
|
+
end
|
320
|
+
|
321
|
+
return searched if searched
|
322
|
+
|
323
|
+
# Simple operation search
|
324
|
+
case operation
|
325
|
+
when :eq then relation.where(attribute.eq(term))
|
326
|
+
when :not_eq then relation.where(attribute.not_eq(term))
|
327
|
+
when :matches then relation.where(attribute.matches("%#{term}%"))
|
328
|
+
when :does_not_match then relation.where(attribute.does_not_match("%#{term}%"))
|
329
|
+
when :starts_with then relation.where(attribute.matches("#{term}%"))
|
330
|
+
when :ends_with then relation.where(attribute.matches("%#{term}"))
|
331
|
+
when :gt then relation.where(attribute.gt(term))
|
332
|
+
when :gteq then relation.where(attribute.gteq(term))
|
333
|
+
when :lt then relation.where(attribute.lt(term))
|
334
|
+
when :lteq then relation.where(attribute.lteq(term))
|
335
|
+
else raise("Unexpected operation: #{operation}")
|
187
336
|
end
|
188
337
|
end
|
189
338
|
|
@@ -195,11 +344,6 @@ module Effective
|
|
195
344
|
return relation.where(klass.primary_key => value)
|
196
345
|
end
|
197
346
|
|
198
|
-
# If the value is 3-something-like-this
|
199
|
-
if (values = value.to_s.split('-')).length > 0 && (maybe_id = values.first).present?
|
200
|
-
return relation.where(klass.primary_key => maybe_id) if (maybe_id.to_i.to_s == maybe_id)
|
201
|
-
end
|
202
|
-
|
203
347
|
# If the user specifies columns. Filter out invalid ones for this klass
|
204
348
|
if columns.present?
|
205
349
|
columns = Array(columns).map(&:to_s) - [nil, '']
|
@@ -238,81 +382,6 @@ module Effective
|
|
238
382
|
|
239
383
|
private
|
240
384
|
|
241
|
-
def search_by_associated_conditions(association, value, fuzzy: nil)
|
242
|
-
resource = Effective::Resource.new(association)
|
243
|
-
|
244
|
-
# Search the target model for its matching records / keys
|
245
|
-
relation = resource.search_any(value, fuzzy: fuzzy)
|
246
|
-
|
247
|
-
if association.options[:as] # polymorphic
|
248
|
-
relation = relation.where(association.type => klass.name)
|
249
|
-
end
|
250
|
-
|
251
|
-
# key: the id, or associated_id on my table
|
252
|
-
# keys: the ids themselves as per the target table
|
253
|
-
if association.macro == :belongs_to && association.options[:polymorphic]
|
254
|
-
key = sql_column(association.foreign_key)
|
255
|
-
keys = relation.pluck((relation.klass.primary_key rescue nil))
|
256
|
-
elsif association.macro == :belongs_to
|
257
|
-
key = sql_column(association.foreign_key)
|
258
|
-
keys = relation.pluck(association.klass.primary_key)
|
259
|
-
elsif association.macro == :has_and_belongs_to_many
|
260
|
-
key = sql_column(klass.primary_key)
|
261
|
-
values = relation.pluck(association.source_reflection.klass.primary_key).uniq.compact
|
262
|
-
|
263
|
-
keys = if value == 'nil'
|
264
|
-
klass.where.not(klass.primary_key => klass.joins(association.name)).pluck(klass.primary_key)
|
265
|
-
else
|
266
|
-
klass.joins(association.name)
|
267
|
-
.where(association.name => { association.source_reflection.klass.primary_key => values })
|
268
|
-
.pluck(klass.primary_key)
|
269
|
-
end
|
270
|
-
elsif association.options[:through].present?
|
271
|
-
scope = association.through_reflection.klass.all
|
272
|
-
|
273
|
-
if association.source_reflection.options[:polymorphic]
|
274
|
-
reflected_klass = association.klass
|
275
|
-
scope = scope.where(association.source_reflection.foreign_type => reflected_klass.name)
|
276
|
-
else
|
277
|
-
reflected_klass = association.source_reflection.klass
|
278
|
-
end
|
279
|
-
|
280
|
-
if association.through_reflection.macro == :belongs_to
|
281
|
-
key = association.through_reflection.foreign_key
|
282
|
-
pluck_key = association.through_reflection.klass.primary_key
|
283
|
-
else
|
284
|
-
key = sql_column(klass.primary_key)
|
285
|
-
pluck_key = association.through_reflection.foreign_key
|
286
|
-
end
|
287
|
-
|
288
|
-
if value == 'nil'
|
289
|
-
keys = klass.where.not(klass.primary_key => scope.pluck(pluck_key)).pluck(klass.primary_key)
|
290
|
-
else
|
291
|
-
keys = scope.where(association.source_reflection.foreign_key => relation).pluck(pluck_key)
|
292
|
-
end
|
293
|
-
|
294
|
-
elsif association.macro == :has_many
|
295
|
-
key = sql_column(klass.primary_key)
|
296
|
-
|
297
|
-
keys = if value == 'nil'
|
298
|
-
klass.where.not(klass.primary_key => resource.klass.pluck(association.foreign_key)).pluck(klass.primary_key)
|
299
|
-
else
|
300
|
-
relation.pluck(association.foreign_key)
|
301
|
-
end
|
302
|
-
|
303
|
-
elsif association.macro == :has_one
|
304
|
-
key = sql_column(klass.primary_key)
|
305
|
-
|
306
|
-
keys = if value == 'nil'
|
307
|
-
klass.where.not(klass.primary_key => resource.klass.pluck(association.foreign_key)).pluck(klass.primary_key)
|
308
|
-
else
|
309
|
-
relation.pluck(association.foreign_key)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
"#{key} IN (#{(keys.uniq.compact.presence || [0]).join(',')})"
|
314
|
-
end
|
315
|
-
|
316
385
|
def order_by_associated_conditions(association, sort: nil, direction: :asc, limit: nil)
|
317
386
|
resource = Effective::Resource.new(association)
|
318
387
|
|
@@ -38,6 +38,15 @@ module Effective
|
|
38
38
|
name.to_s.downcase == 'desc' ? 'DESC' : 'ASC'
|
39
39
|
end
|
40
40
|
|
41
|
+
def sql_operation(name, as: nil)
|
42
|
+
sql_type = (as || sql_type(name))
|
43
|
+
|
44
|
+
case sql_type
|
45
|
+
when :boolean, :decimal, :integer, :price, :date, :datetime, :percent then :eq
|
46
|
+
else :matches
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
41
50
|
# This is for EffectiveDatatables (col as:)
|
42
51
|
# Might be :name, or 'users.name'
|
43
52
|
def sql_type(name)
|
data/lib/effective_resources.rb
CHANGED
@@ -172,4 +172,10 @@ module EffectiveResources
|
|
172
172
|
|
173
173
|
end
|
174
174
|
|
175
|
+
def self.replace_nested_attributes(attributes)
|
176
|
+
attributes.reject { |k, values| truthy?(values[:_destroy]) }.inject({}) do |h, (key, values)|
|
177
|
+
h[key] = values.reject { |k, v| k == 'id' || k == '_destroy' }; h
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
175
181
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_resources
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|