effective_resources 2.1.4 → 2.2.1

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
  SHA256:
3
- metadata.gz: 5c6a9d06e7d62a4fa96c365b8e6386d4229585ed5c0963b3f55b435ed4b7cbf4
4
- data.tar.gz: 84459f1187673d432756a4e3fccf6b163f3b5f55af26a7c1c485938e892d9e95
3
+ metadata.gz: 8f9e795410769087135de28ce4b8c46a48de30d72dc9feeaa48a96966f059c43
4
+ data.tar.gz: 488c2b300e0b05e1c111093e903aae654ab7867f952b66b81dbdd2c5fce46159
5
5
  SHA512:
6
- metadata.gz: f76ef089d1b702f51948cf5ec7b03fc8fe9529428190225b9e27bddbc91c83c3e8d9b01911a2ae5d97efcae22cd8e2f77dd0d642b32b5184b459a6ccb4e3bbfa
7
- data.tar.gz: 6e13de73624c865c3312d2af94816890769599ed2aa1d89e4cde5251d545d25583a14293b04d2a152cc493c2c6c222015cba326e09dec19310771668bda2b8ab
6
+ metadata.gz: b6a2ca614bafbeef5787bcaf49a68d467c0707c3610e5b692d4d58d40295a630b15baa828c2ec71d8837c76372817db6a4ec78e4eb96b391517815d1edcfae99
7
+ data.tar.gz: 0deb208420dc1591c95cd23735ef4c4f843411d91a071cc515f492225e8c1a63f9d3415c66257357d7651aed58ca3f3f842a6508aa8eb1e1b0cd658325071879
@@ -68,6 +68,7 @@ module ActsAsPurchasableWizard
68
68
  order.billing_address = owner.billing_address if owner.try(:billing_address).present?
69
69
 
70
70
  # Important to add/remove anything
71
+ # This will update the prices, but the purchasables must be persisted
71
72
  order.save!
72
73
 
73
74
  order
@@ -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.to_param] } }
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.to_param] } }
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.to_param] } }
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.to_param] }.sort { |x, y| x[0] <=> y[0] } }
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,279 @@ module Effective
65
65
  end
66
66
  end
67
67
 
68
- def search(name, value, as: nil, fuzzy: true, sql_column: 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
- sql_column ||= sql_column(name)
72
- sql_type = (as || sql_type(name))
73
- fuzzy = true unless fuzzy == false
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
- association = associated(name)
80
-
81
- term = Effective::Attribute.new(sql_type, klass: (association.try(:klass) rescue nil) || klass).parse(value, name: name)
82
-
83
- # term == 'nil' rescue false is a Rails 4.1 fix, where you can't compare a TimeWithZone to 'nil'
84
- if (term == 'nil' rescue false) && ![:has_and_belongs_to_many, :has_many, :has_one, :belongs_to, :belongs_to_polymorphic, :effective_roles].include?(sql_type)
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
- case sql_type
89
- when :belongs_to
90
- if term == 'nil'
91
- relation.where(is_null(association.foreign_key))
92
- else
93
- relation.where(search_by_associated_conditions(association, term, fuzzy: fuzzy))
94
- end
95
- when :belongs_to_polymorphic
96
- (type, id) = term.split('_')
97
-
98
- if term == 'nil'
99
- relation.where(is_null("#{sql_column}_id")).where(is_null("#{sql_column}_type"))
100
- elsif type.present? && id.present? # This was from a polymorphic select
101
- relation.where("#{sql_column}_id = ?", id).where("#{sql_column}_type = ?", type)
88
+ def search_associated(name, value, as:, operation:)
89
+ reflection = associated(name)
90
+
91
+ raise("expected to find #{relation.klass.name} #{name} reflection") unless reflection
92
+ raise("unexpected search_associated operation #{operation || 'nil'}") unless [:eq, :matches, :does_not_match, :sql].include?(operation)
93
+
94
+ # Parse values
95
+ value_ids = value.kind_of?(Array) ? value : (value.to_s.split(/,|\s|\|/) - [nil, '', ' '])
96
+ value_sql = Arel.sql(value) if value.kind_of?(String)
97
+
98
+ # Foreign id and type
99
+ foreign_id = reflection.foreign_key
100
+ foreign_type = reflection.foreign_key.to_s.chomp('_id') + '_type'
101
+
102
+ # belongs_to polymorphic
103
+ retval = if as == :belongs_to_polymorphic
104
+ (type, id) = value.to_s.split('_')
105
+
106
+ if type.present? && id.present? # This was from a polymorphic select
107
+ case operation
108
+ when :eq
109
+ relation.where(foreign_type => type, foreign_id => id)
110
+ when :matches
111
+ relation.where(foreign_type => type, foreign_id => id)
112
+ when :does_not_match
113
+ relation.where.not(foreign_type => type, foreign_id => id)
114
+ when :sql
115
+ if (relation.where(value_sql).present? rescue :invalid) != :invalid
116
+ relation.where(value_sql)
117
+ else
118
+ relation
119
+ end
120
+ end
102
121
  else # Maybe from a string field
103
- collection = relation.none
122
+ associated = relation.none
104
123
 
105
- relation.unscoped.distinct("#{name}_type").pluck("#{name}_type").each do |klass_name|
124
+ relation.unscoped.distinct(foreign_type).pluck(foreign_type).each do |klass_name|
106
125
  next if klass_name.nil?
107
126
 
108
127
  resource = Effective::Resource.new(klass_name)
109
128
  next unless resource.klass.present?
110
129
 
111
- collection = collection.or(relation.where("#{name}_id": resource.search_any(term, fuzzy: fuzzy), "#{name}_type": klass_name))
130
+ associated = associated.or(relation.where(foreign_id => resource.search_any(value), foreign_type => klass_name))
112
131
  end
113
132
 
114
- collection
115
- end
116
- when :has_and_belongs_to_many, :has_many, :has_one
117
- relation.where(search_by_associated_conditions(association, term, fuzzy: fuzzy))
118
- when :effective_addresses
119
- relation.where(id: Effective::Resource.new(association).search_any(value, fuzzy: fuzzy).pluck(:addressable_id))
120
- when :effective_obfuscation
121
- # If value == term, it's an invalid deobfuscated id
122
- relation.where("#{sql_column} = ?", (value == term ? 0 : term))
123
- when :effective_roles
124
- relation.with_role(term)
125
- when :active_storage
126
- relation.send("with_attached_#{name}").references("#{name}_attachment")
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
133
+ case operation
134
+ when :eq
135
+ relation.where(id: associated.select(:id))
136
+ when :matches
137
+ relation.where(id: associated.select(:id))
138
+ when :does_not_match
139
+ relation.where.not(id: associated.select(:id))
140
+ when :sql
141
+ if (relation.where(value_sql).present? rescue :invalid) != :invalid
142
+ relation.where(value_sql)
143
+ else
144
+ relation
145
+ end
140
146
  end
141
- )
142
- relation.where("#{sql_column} >= ? AND #{sql_column} <= ?", term, end_at)
143
- when :time
144
- timed = relation.where("EXTRACT(hour from #{sql_column}) = ?", term.utc.hour)
145
- timed = timed.where("EXTRACT(minute from #{sql_column}) = ?", term.utc.min) if term.min > 0
146
- timed
147
- when :decimal, :currency
148
- if fuzzy && (term.round(0) == term) && value.to_s.include?('.') == false
149
- if term < 0
150
- relation.where("#{sql_column} <= ? AND #{sql_column} > ?", term, term-1.0)
147
+ end
148
+
149
+ # belongs_to non-polymorphic
150
+ elsif as == :belongs_to
151
+ foreign_collection = reflection.klass.all
152
+ foreign_collection = reflection.klass.where(foreign_type => relation.klass.name) if reflection.klass.new.respond_to?(foreign_type)
153
+
154
+ case operation
155
+ when :eq
156
+ associated = foreign_collection.where(id: value_ids)
157
+ relation.where(foreign_id => associated.select(:id))
158
+ when :matches
159
+ associated = Resource.new(foreign_collection).search_any(value)
160
+ relation.where(foreign_id => associated.select(:id))
161
+ when :does_not_match
162
+ associated = Resource.new(foreign_collection).search_any(value)
163
+ relation.where.not(foreign_id => associated.select(:id))
164
+ when :sql
165
+ if (foreign_collection.where(value_sql).present? rescue :invalid) != :invalid
166
+ associated = foreign_collection.where(value_sql)
167
+ relation.where(foreign_id => associated.select(:id))
151
168
  else
152
- relation.where("#{sql_column} >= ? AND #{sql_column} < ?", term, term+1.0)
169
+ relation
153
170
  end
154
- else
155
- relation.where("#{sql_column} = ?", term)
156
171
  end
157
- when :duration
158
- if fuzzy && (term % 60 == 0) && value.to_s.include?('m') == false
159
- if term < 0
160
- relation.where("#{sql_column} <= ? AND #{sql_column} > ?", term, term-60)
172
+
173
+ # has_and_belongs_to_many
174
+ elsif as == :has_and_belongs_to_many
175
+ foreign_collection = reflection.source_reflection.klass.all
176
+
177
+ habtm = foreign_collection.klass.reflect_on_all_associations.find { |ass| ass.macro == :has_and_belongs_to_many && ass.join_table == reflection.join_table }
178
+ raise("expected a matching HABTM reflection") unless habtm
179
+
180
+ case operation
181
+ when :eq
182
+ associated = foreign_collection.where(id: value_ids)
183
+ relation.where(id: associated.joins(habtm.name).select(foreign_id))
184
+ when :matches
185
+ associated = Resource.new(foreign_collection).search_any(value)
186
+ relation.where(id: associated.joins(habtm.name).select(foreign_id))
187
+ when :does_not_match
188
+ associated = Resource.new(foreign_collection).search_any(value)
189
+ relation.where.not(id: associated.joins(habtm.name).select(foreign_id))
190
+ when :sql
191
+ if (foreign_collection.where(value_sql).present? rescue :invalid) != :invalid
192
+ associated = foreign_collection.where(value_sql)
193
+ relation.where(id: associated.joins(habtm.name).select(foreign_id))
161
194
  else
162
- relation.where("#{sql_column} >= ? AND #{sql_column} < ?", term, term+60)
195
+ relation
163
196
  end
197
+ end
198
+
199
+ # has_many through
200
+ elsif reflection.options[:through].present?
201
+ reflected_klass = if reflection.source_reflection.options[:polymorphic]
202
+ reflection.klass
164
203
  else
165
- relation.where("#{sql_column} = ?", term)
204
+ reflection.source_reflection.klass
166
205
  end
167
- when :integer
168
- relation.where("#{sql_column} = ?", term)
169
- when :percent
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}%")
206
+
207
+ reflected_id = if reflection.source_reflection.macro == :belongs_to
208
+ reflection.source_reflection.foreign_key # to do check this
176
209
  else
177
- relation.where("#{sql_column} = ?", term)
210
+ reflection.source_reflection.klass.primary_key # group_id
178
211
  end
179
- when :uuid
180
- if fuzzy
181
- relation.where("#{sql_column}::text #{ilike} ?", "%#{term}%")
212
+
213
+ foreign_id = if reflection.through_reflection.macro == :belongs_to
214
+ reflection.through_reflection.klass.primary_key # to do check this
182
215
  else
183
- relation.where("#{sql_column}::text = ?", term)
216
+ reflection.through_reflection.foreign_key # user_id
217
+ end
218
+
219
+ # Build the through collection
220
+ through = reflection.through_reflection.klass.all # group mates
221
+
222
+ if reflection.source_reflection.options[:polymorphic]
223
+ through = through.where(reflection.source_reflection.foreign_type => reflected_klass.name)
224
+ end
225
+
226
+ # Search the associated class
227
+ case operation
228
+ when :eq
229
+ associated = through.where(reflected_id => value_ids)
230
+ relation.where(id: associated.select(foreign_id))
231
+ when :matches
232
+ reflected = Resource.new(reflected_klass).search_any(value)
233
+ associated = through.where(reflected_id => reflected)
234
+ relation.where(id: associated.select(foreign_id))
235
+ when :does_not_match
236
+ reflected = Resource.new(reflected_klass).search_any(value)
237
+ associated = through.where(reflected_id => reflected)
238
+ relation.where.not(id: associated.select(foreign_id))
239
+ when :sql
240
+ if (reflected_klass.where(value_sql).present? rescue :invalid) != :invalid
241
+ reflected = reflected_klass.where(value_sql)
242
+ associated = through.where(reflected_id => reflected)
243
+ relation.where(id: associated.select(foreign_id))
244
+ else
245
+ relation
246
+ end
247
+ end
248
+
249
+ # has_many and has_one
250
+ elsif (as == :has_many || as == :has_one)
251
+ foreign_collection = reflection.klass.all
252
+ foreign_collection = reflection.klass.where(foreign_type => relation.klass.name) if reflection.klass.new.respond_to?(foreign_type)
253
+
254
+ case operation
255
+ when :eq
256
+ associated = foreign_collection.where(id: value_ids)
257
+ relation.where(id: associated.select(foreign_id))
258
+ when :matches
259
+ associated = Resource.new(foreign_collection).search_any(value)
260
+ relation.where(id: associated.select(foreign_id))
261
+ when :does_not_match
262
+ associated = Resource.new(foreign_collection).search_any(value)
263
+ relation.where.not(id: associated.select(foreign_id))
264
+ when :sql
265
+ if (foreign_collection.where(value_sql).present? rescue :invalid) != :invalid
266
+ associated = foreign_collection.where(value_sql)
267
+ relation.where(id: associated.select(foreign_id))
268
+ else
269
+ relation
270
+ end
184
271
  end
185
- else
186
- raise "unsupported sql type #{sql_type}"
272
+ end
273
+
274
+ retval || raise("unable to search associated #{as} #{operation} #{name} for #{value}")
275
+ end
276
+
277
+ def search_attribute(name, value, as:, operation:)
278
+ raise 'expected relation to be present' unless relation
279
+
280
+ attribute = relation.arel_table[name]
281
+
282
+ # Normalize the term.
283
+ # If you pass an email attribute it can return nil so we return the full value
284
+ term = Attribute.new(as).parse(value, name: name) || value
285
+
286
+ searched = case as
287
+ when :active_storage
288
+ relation.send("with_attached_#{name}").references("#{name}_attachment")
289
+ .where(ActiveStorage::Blob.arel_table[:filename].matches("%#{term}%"))
290
+
291
+ when :date, :datetime
292
+ if value.kind_of?(String)
293
+ end_at = (
294
+ case (value.to_s.scan(/(\d+)/).flatten).length
295
+ when 1 ; term.end_of_year # Year
296
+ when 2 ; term.end_of_month # Year-Month
297
+ when 3 ; term.end_of_day # Year-Month-Day
298
+ when 4 ; term.end_of_hour # Year-Month-Day Hour
299
+ when 5 ; term.end_of_minute # Year-Month-Day Hour-Minute
300
+ when 6 ; term + 1.second # Year-Month-Day Hour-Minute-Second
301
+ else term
302
+ end
303
+ )
304
+
305
+ relation.where(attribute.gteq(term)).where(attribute.lteq(end_at))
306
+ end
307
+
308
+ when :effective_obfuscation
309
+ term = Attribute.new(as, klass: (associated(name).try(:klass) || klass)).parse(value, name: name)
310
+ relation.where(attribute.eq((value == term ? 0 : term)))
311
+
312
+ when :effective_addresses
313
+ association = associated(name)
314
+ associated = Resource.new(association).search_any(value)
315
+ relation.where(id: associated.where(addressable_type: klass.name).select(:addressable_id))
316
+
317
+ when :effective_roles
318
+ relation.with_role(term)
319
+
320
+ when :time
321
+ timed = relation.where("EXTRACT(hour from #{sql_column}) = ?", term.utc.hour)
322
+ timed = timed.where("EXTRACT(minute from #{sql_column}) = ?", term.utc.min) if term.min > 0
323
+ timed
324
+ end
325
+
326
+ return searched if searched
327
+
328
+ # Simple operation search
329
+ case operation
330
+ when :eq then relation.where(attribute.eq(term))
331
+ when :not_eq then relation.where(attribute.not_eq(term))
332
+ when :matches then relation.where(attribute.matches("%#{term}%"))
333
+ when :does_not_match then relation.where(attribute.does_not_match("%#{term}%"))
334
+ when :starts_with then relation.where(attribute.matches("#{term}%"))
335
+ when :ends_with then relation.where(attribute.matches("%#{term}"))
336
+ when :gt then relation.where(attribute.gt(term))
337
+ when :gteq then relation.where(attribute.gteq(term))
338
+ when :lt then relation.where(attribute.lt(term))
339
+ when :lteq then relation.where(attribute.lteq(term))
340
+ else raise("Unexpected operation: #{operation}")
187
341
  end
188
342
  end
189
343
 
@@ -195,11 +349,6 @@ module Effective
195
349
  return relation.where(klass.primary_key => value)
196
350
  end
197
351
 
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
352
  # If the user specifies columns. Filter out invalid ones for this klass
204
353
  if columns.present?
205
354
  columns = Array(columns).map(&:to_s) - [nil, '']
@@ -238,81 +387,6 @@ module Effective
238
387
 
239
388
  private
240
389
 
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
390
  def order_by_associated_conditions(association, sort: nil, direction: :asc, limit: nil)
317
391
  resource = Effective::Resource.new(association)
318
392
 
@@ -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)
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '2.1.4'.freeze
2
+ VERSION = '2.2.1'.freeze
3
3
  end
@@ -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.1.4
4
+ version: 2.2.1
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: 2022-11-29 00:00:00.000000000 Z
11
+ date: 2023-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails