dynamic-records-meritfront 2.0.3 → 2.0.9

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: b0ad57039c2e650f4882c75aaeccca4fe55a771db29e0552ef648a9eaf974be8
4
- data.tar.gz: 0af2b5a0f1add956c8b6029196237b9945c820204c114498078f8bf80be90ecf
3
+ metadata.gz: f804fba287c6722d84da7333db7277f5aea64481eb04c87001e2b66b0a4d78c9
4
+ data.tar.gz: 8e6da4032c10896df9f051c804654fac622ea078b2388fd6d80648abd0a380b7
5
5
  SHA512:
6
- metadata.gz: 86ca4444f4848bb8af6389f005faf9a9813b9a49f0c0b31450d95d4317470c2c0e3e4b6435d3fba1cf57a7f7f1a02b7763a0dde9861b59a53cfac1681e4c6cbb
7
- data.tar.gz: 29593f3c3ec593384c573e74ff2737e2b97e77cb38dbc371c3847693488095a2b828b316fbe105a0a599efa430c33c611f17637808c51f27932d47b76fccbd45
6
+ metadata.gz: 0a0502e1057ff93ba5c351b07a037ab83c900182bf467ef038ebc4d7f4b69e2c8c1cb72807154262c9d3384a7c7dcc19d4cd9d2ff61b136ae964b2d22079fb13
7
+ data.tar.gz: 64c188c396f7ef7daf3d4bef8ff7fcbe93b8feb4727717575e16363487a2b372dc3f6e08123d4e92d533fe1b5979f6592334e471222f8c17fa605108cdf0e4e5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamic-records-meritfront (2.0.3)
4
+ dynamic-records-meritfront (2.0.9)
5
5
  hashid-rails
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -4,7 +4,7 @@ Dyanmic Records Meritfront contains some helpers methods for active record. Thes
4
4
  1. communicate with the frontend quicker and more effectively through Global HashIds
5
5
  2. communicate with the backend more effectively with raw sql queries. This becomes especially relevant when you hit the limits of Active Record Relations and the usual way of querying in rails. For instance, if you have a page-long dynamic sql query.
6
6
 
7
- I dont tend to get much feedback, so any given would be appreciated.
7
+ Note that postgres is a requirement for this gem. I dont tend to get much feedback, so any given would be appreciated.
8
8
 
9
9
  ## Installation
10
10
 
@@ -30,6 +30,7 @@ Or install it yourself as:
30
30
  class ApplicationRecord < ActiveRecord::Base
31
31
  self.abstract_class = true
32
32
  include DynamicRecordsMeritfront
33
+ DYNAMIC_SQL_RAW = false #<--- not required, but suggested to be turned off. Can be switched on for a per-request basis. Make sure this line is after include statement.
33
34
  end
34
35
  ```
35
36
 
@@ -75,8 +76,8 @@ obj.has_association?(:votes) #false
75
76
  ```
76
77
  </details>
77
78
 
78
- #### self.headache_sql(name, sql, opts = { })
79
- A better and safer way to write sql.
79
+ #### self.dynamic_sql(name, sql, opts = { })
80
+ A better and safer way to write sql. Can return either a Hash, ActiveRecord::Response object, or an instantiated model.
80
81
  with options:
81
82
  - instantiate_class: returns User, Post, etc objects instead of straight sql output.
82
83
  I prefer doing the alterantive
@@ -87,14 +88,15 @@ with options:
87
88
  - multi_query: allows more than one query (you can seperate an insert and an update with ';' I dont know how else to say it.)
88
89
  this disables other options including arguments (except name_modifiers). Not sure how it effects prepared statements.
89
90
  - async: Gets passed to ActiveRecord::Base.connection.exec_query as a parameter. See that methods documentation for more. I was looking through the source code, and I think it only effects how it logs to the logfile?
91
+ - raw: whether to return a ActiveRecord::Response object or a hash
90
92
  - other options: considered sql arguments
91
-
93
+
92
94
  <details>
93
95
  <summary>example usage</summary>
94
96
  Delete Friend Requests between two users after they have become friends.
95
97
 
96
98
  ```ruby
97
- ApplicationRecord.headache_sql("remove_friend_requests_before_creating_friend", %Q{
99
+ ApplicationRecord.dynamic_sql("remove_friend_requests_before_creating_friend", %Q{
98
100
  DELETE FROM friend_requests
99
101
  WHERE (requestie_id = :uid and requester_id = :other_user_id) OR
100
102
  (requester_id = :uid and requestie_id = :other_user_id)
@@ -108,7 +110,7 @@ Get all users who have made a friend request to a particular user with an option
108
110
  This is an example of why this method is good for dynamic prepared statements.
109
111
 
110
112
  ```ruby
111
- return User.headache_sql('get_friend_requests', %Q{
113
+ return User.dynamic_sql('get_friend_requests', %Q{
112
114
  SELECT * FROM (
113
115
  SELECT other_user.id, ..., friend_requests.created_at
114
116
  FROM users
@@ -123,6 +125,28 @@ This is an example of why this method is good for dynamic prepared statements.
123
125
  ])
124
126
  ```
125
127
  </details>
128
+
129
+ <details>
130
+ <summary>access non-standard column for table with a ActiveRecord model</summary>
131
+
132
+ ```ruby
133
+ #get a normal test vote
134
+ test = Vote.dynamic_sql('test', %Q{
135
+ SELECT id FROM votes LIMIT 1
136
+ }).first
137
+ v.inspect # "#<Vote id: 696969>"
138
+ v.dynamic # nil
139
+
140
+ #get a cool test vote. Note that is_this_vote_cool is not on the vote table.
141
+ test = Vote.dynamic_sql('test', %Q{
142
+ SELECT id, 'yes' AS is_this_vote_cool FROM votes LIMIT 1
143
+ }).first
144
+ test.inspect # "#<Vote id: 696969>" we dont have the dynamic attributes as normal ones because of some implementation issues and some real issues to do with accidently logging sensative info.
145
+ test.dynamic # {:is_this_vote_cool=>"yes"}
146
+ test.dynamic[:is_this_vote_cool] # "yes"
147
+ ```
148
+ </details>
149
+
126
150
  <details>
127
151
  <summary>example usage with selecting records that match list of ids</summary>
128
152
  Get users who match a list of ids. Uses a postgresql Array, see the potential issues section
@@ -147,7 +171,7 @@ Do an upsert
147
171
  t, #created_at
148
172
  t, #updated_at
149
173
  ]}
150
- ApplicationRecord.headache_sql("upsert_conversation_invites_2", %Q{
174
+ ApplicationRecord.dynamic_sql("upsert_conversation_invites_2", %Q{
151
175
  INSERT INTO conversation_participants (user_id, conversation_id, invited_by, created_at, updated_at)
152
176
  VALUES :rows
153
177
  ON CONFLICT (conversation_id,user_id)
@@ -164,10 +188,9 @@ This will output sql similar to below. Note this can be done for multiple conver
164
188
  ```
165
189
  </details>
166
190
 
167
-
168
191
 
169
- #### self.headache_preload(records, associations)
170
- Preloads from a list of records, and not from a ActiveRecord_Relation. This will be useful when using the above headache_sql method (as it returns a list of records, and not a record relation).
192
+ #### self.dynamic_preload(records, associations)
193
+ Preloads from a list of records, and not from a ActiveRecord_Relation. This will be useful when using the above headache_sql method (as it returns a list of records, and not a record relation). This is basically the same as a normal relation preload but it works on a list.
171
194
 
172
195
  <details>
173
196
  <summary>example usage</summary>
@@ -179,9 +202,133 @@ Preload :votes on some comments. :votes is an active record has_many relation.
179
202
  })
180
203
  ApplicationRecord.headache_preload(comments, [:votes])
181
204
  puts comments[0].votes #this line should be preloaded and hence not call the database
205
+
206
+ #note that this above is basically the same as doing the below assuming there is a comments relation on the user model.
207
+ user.comments.preload(:votes)
182
208
  ```
183
209
  </details>
184
210
 
211
+ #### self.dynamic_instaload_sql(name, insta_array, opts = { })
212
+ *instaloads* a bunch of diffrent models at the same time by casting them to json before returning them. Kinda cool. Seems to be more efficient to preloading when i tested it.
213
+ - name is passed to dynamic_sql and is the name of the sql request
214
+ - opts are passed to dynamic_sql (except for the raw option which is set to true. Raw output is not allowed on this request)
215
+ - insta-array is an array of instaload method outputs. See examples for more.
216
+
217
+ <details>
218
+ <summary>example usage</summary>
219
+ #get list of users, those users friends, and who those users follow, all in one request.
220
+
221
+ ```ruby
222
+ # the ruby entered
223
+ output = ApplicationRecord.swiss_instaload_sql('test', [
224
+ User.instaload('SELECT id FROM users WHERE users.id = ANY (:user_ids) AND users.created_at > :time', table_name: 'limited_users', relied_on: true),
225
+ User.instaload(%Q{
226
+ SELECT friends.smaller_user_id AS id, friends.bigger_user_id AS friended_to
227
+ FROM friends INNER JOIN limited_users ON limited_users.id = bigger_user_id
228
+ UNION
229
+ SELECT friends.bigger_user_id AS id, friends.smaller_user_id AS friended_to
230
+ FROM friends INNER JOIN limited_users ON limited_users.id = smaller_user_id
231
+ }, table_name: 'users_friends'),
232
+ ApplicationRecord.instaload(%Q{
233
+ SELECT follows.followable_id, follows.follower_id
234
+ FROM follows
235
+ INNER JOIN limited_users ON follows.follower_id = limited_users.id
236
+ }, table_name: "users_follows")
237
+ ], user_ids: uids, time: t)
238
+ ```
239
+ the sql:
240
+ ```sql
241
+ WITH limited_users AS (
242
+ SELECT id FROM users WHERE users.id = ANY ($1) AND users.created_at > $2
243
+ )
244
+ SELECT row_to_json(limited_users.*) AS row, 'User' AS _klass, 'limited_users' AS _table_name FROM limited_users
245
+ UNION ALL
246
+ SELECT row_to_json(users_friends.*) AS row, 'User' AS _klass, 'users_friends' AS _table_name FROM (
247
+ SELECT friends.smaller_user_id AS id, friends.bigger_user_id AS friended_to
248
+ FROM friends INNER JOIN limited_users ON limited_users.id = bigger_user_id
249
+ UNION
250
+ SELECT friends.bigger_user_id AS id, friends.smaller_user_id AS friended_to
251
+ FROM friends INNER JOIN limited_users ON limited_users.id = smaller_user_id
252
+ ) AS users_friends
253
+ UNION ALL
254
+ SELECT row_to_json(users_follows.*) AS row, 'ApplicationRecord' AS _klass, 'users_follows' AS _table_name FROM (
255
+ SELECT follows.followable_id, follows.follower_id
256
+ FROM follows
257
+ INNER JOIN limited_users ON follows.follower_id = limited_users.id
258
+ ) AS users_follows
259
+ ```
260
+
261
+ the output:
262
+ ```ruby
263
+ {
264
+ "limited_users"=>[#<User id: 3>, #<User id: 1>, #<User id: 4>],
265
+ "users_friends"=>[
266
+ #<User id: 21>,
267
+ #<User id: 5>,
268
+ ...],
269
+ "users_follows"=> [
270
+ {"followable_id"=>22, "follower_id"=>4},
271
+ {"followable_id"=>23, "follower_id"=>4}, ...]
272
+ }
273
+ ```
274
+ </details>
275
+
276
+ #### self.dynamic_attach(instaload_sql_output, base_name, attach_name, base_on: nil, attach_on: nil, one_to_one: false)
277
+ taking the output of the dynamic_instaload_sql, this method attaches the models together so they have relations. Note: still undecided on using singleton attr_accessors or putting the relationship on the model.dynamic hash. Its currently using the accessors.
278
+ - instaload_sql_output: output of above dynamic_instaload_sql
279
+ - base_name: the name of the table we will be attaching to
280
+ - attach_name: the name of the table that will be attached
281
+ - base_on: put a proc here to override the matching behavior on the base table. Default is {|user| user.id}
282
+ - attach_on: put a proc here to override the matching behavior on the attach table. Default is {|post| post.user_id}
283
+ - one_to_one: switches between a one-to-one relationship or not
284
+
285
+ <details>
286
+ <summary> attach information for each limited_user in the dynamic_instaload_sql example </summary>
287
+
288
+ ```ruby
289
+
290
+ ApplicationRecord.dynamic_attach(out, 'limited_users', 'users_friends', attach_on: Proc.new {|users_friend|
291
+ users_friend.dynamic[:friended_to]
292
+ })
293
+ ApplicationRecord.dynamic_attach(out, 'limited_users', 'users_follows', attach_on: Proc.new {|follow|
294
+ follow['follower_id']
295
+ })
296
+ pp out['limited_users'].map{|o| {id: o.id, users_friends: o.users_friends.first(4), users_follows: o.users_follows.first(4)}}
297
+
298
+ ```
299
+
300
+ printed output:
301
+ ```ruby
302
+ [{:id=>3,
303
+ :users_friends=>[#<User id: 21>, #<User id: 5>, #<User id: 6>],
304
+ :users_follows=>
305
+ [{"followable_id"=>935, "follower_id"=>3},
306
+ {"followable_id"=>938, "follower_id"=>3},
307
+ {"followable_id"=>939, "follower_id"=>3},
308
+ {"followable_id"=>932, "follower_id"=>3}]},
309
+ {:id=>14,
310
+ :users_friends=>
311
+ [#<User id: 18>, #<User id: 9>, #<User id: 21>, #<User id: 5>],
312
+ :users_follows=>
313
+ [{"followable_id"=>936, "follower_id"=>14},
314
+ {"followable_id"=>937, "follower_id"=>14},
315
+ {"followable_id"=>938, "follower_id"=>14},
316
+ {"followable_id"=>939, "follower_id"=>14}]},
317
+ {:id=>9,
318
+ :users_friends=>
319
+ [#<User id: 19>, #<User id: 15>, #<User id: 14>, #<User id: 7>],
320
+ :users_follows=>
321
+ [{"followable_id"=>938, "follower_id"=>9},
322
+ {"followable_id"=>937, "follower_id"=>9},
323
+ {"followable_id"=>932, "follower_id"=>9},
324
+ {"followable_id"=>933, "follower_id"=>9}]}, ... ]
325
+
326
+ ```
327
+
328
+ </details>
329
+
330
+
331
+
185
332
  ### Hashed Global IDS
186
333
 
187
334
  hashed global ids look like this: "gid://meritfront/User/K9YI4K". They also have an optional tag so it can also look like "gid://meritfront/User/K9YI4K@user_image". They are based on global ids.
@@ -209,13 +356,7 @@ See the hashid-rails gem for more (https://github.com/jcypret/hashid-rails). Als
209
356
 
210
357
  ## Potential Issues
211
358
 
212
- This gem was made with a postgresql database. Although most of the headache_sql code <i>should</i> be usable between databases, there is no abstracted ActiveRecord array type, and no similar classes to ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array for non-postgresql databases (at least, none I could find). I am not 100% sure that it will be an issue, but it might be.
213
-
214
- Let me know if this actually becomes an issue for someone and I will throw in a workaround.
215
-
216
- ## Next Up
217
- - I have the beginnings of something called swiss_instaload in mind, which will load multiple tables at the same time. For instance instead of Doing a ```usrs = User.all``` combined with a ```usrs.preload(:votes)```, which takes two sql requests, it could be done in one. Its kind of a crazy and dubious idea (efficiency wise), but I have a working prototype. It works by casting everything to json before returning it from the database. There might be a better way to do that long term though.
218
- - will be changing names from headache_* which is a bit negative to swiss_* as in swiss_army_knife which is known for its wide versitility. headache names will become aliases.
359
+ This gem was made with a postgresql database. This could cause a lot of issues with the sql-related methods. I dont have the bandwidth to help switch it elsewhere.
219
360
 
220
361
  ## Changelog
221
362
 
@@ -226,7 +367,16 @@ Let me know if this actually becomes an issue for someone and I will throw in a
226
367
 
227
368
  1.1.11
228
369
  - Added encode option for blind_hgid to allow creation of just a general gid
229
-
370
+
371
+ 2.0.2
372
+ - major changes to the gem
373
+ - many methods changed names from headache... to dynamic... but I threw in some aliases so both work
374
+ - when using dynamic_sql (headache_sql), if you select a column name that doesn't officialy exist on that model, it gets put in the new attr_accessor called dynamic. This allows for more dynamic usage of AR and avoids conflicts with its interal workings (which assume every attribute corresponds to an actual table-column).
375
+ - dynamic_sql can be configured to return a hash rather than the current default which is a ActiveRecord::Response object, this can be configured with the DYNAMIC_SQL_RAW variable on your abstract class (usually ApplicationRecord) or per-request with the new :raw option on dynamic_sql. The hash is way better but I made it optional for backwards compat.
376
+ - dynamic_instaload_sql is now a thing. It seems to be more efficient than preloading. See more above.
377
+ - the output of dynamic_instaload_sql can be made more useful with dynamic_attach. See more above.
378
+ - postgres is now a pretty hard requirement as I use its database features liberally and I am somewhat certain that other databases wont work in the exact same way
379
+
230
380
  ## Contributing
231
381
 
232
382
  Bug reports and pull requests are welcome on GitHub at https://github.com/LukeClancy/dynamic-records-meritfront. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/LukeClancy/dynamic-records-meritfront/blob/master/CODE_OF_CONDUCT.md).
@@ -1,5 +1,5 @@
1
1
 
2
2
  module DynamicRecordsMeritfront
3
- VERSION = '2.0.3'
3
+ VERSION = '2.0.9'
4
4
  end
5
5
  #this file gets overwritten automatically on minor updates, major ones need to be manually changed
@@ -68,6 +68,44 @@ module DynamicRecordsMeritfront
68
68
 
69
69
  module ClassMethods
70
70
 
71
+ def dynamic_print_h(v)
72
+ v = v.dup
73
+ return v.to_h.transform_values{|x|
74
+ dynamic_print(x, print: false)
75
+ }
76
+ end
77
+
78
+ def dynamic_print_arr(v)
79
+ v = v.dup
80
+ return v.map{|x|
81
+ dynamic_print(x, print: false)
82
+ }
83
+ end
84
+
85
+ def dynamic_print_obj(v)
86
+ if v.class < ActiveRecord::Base
87
+ [v, dynamic_print(v.dynamic, print: false)]
88
+ else
89
+ v
90
+ end
91
+ end
92
+
93
+ def dynamic_print(v, print: true)
94
+ return if Rails.env.production?
95
+ if v.class == Hash || v.class == OpenStruct
96
+ ret = dynamic_print_h v
97
+ elsif v.class == Array
98
+ ret = dynamic_print_arr v
99
+ else
100
+ ret = dynamic_print_obj v
101
+ end
102
+ if print
103
+ pp ret
104
+ else
105
+ return ret
106
+ end
107
+ end
108
+
71
109
  def has_run_migration?(nm)
72
110
  #put in a string name of the class and it will say if it has allready run the migration.
73
111
  #good during enum migrations as the code to migrate wont run if enumerate is there
@@ -97,7 +135,7 @@ module DynamicRecordsMeritfront
97
135
  migration = ActiveRecord::Base.connection.migration_context.migrations.filter!{|a|
98
136
  a.name == nm
99
137
  }.first
100
-
138
+
101
139
  #if the migration object is nil, it has not yet been created
102
140
  if migration.nil?
103
141
  Rails.logger.info "No migration found for #{nm}. The migration has not yet been created, or is foreign to this database."
@@ -287,7 +325,8 @@ module DynamicRecordsMeritfront
287
325
  # this disables other options (except name_modifiers). Not sure how it effects prepared statements. Its a fairly useless
288
326
  # command as you can do multiple queries anyway with 'WITH' statements and also gain the other options.
289
327
  # - async does what it says but I haven't used it yet so. Probabably doesn't work
290
- # - instaload is actually insane just look at the example in the readme yolo
328
+ # - raw switches between using a Hash or a ActiveRecord::Response object when used on a abstract class
329
+
291
330
  #
292
331
  # Any other option is assumed to be a sql argument (see other examples in code base)
293
332
 
@@ -420,6 +459,7 @@ module DynamicRecordsMeritfront
420
459
  #{ _dynamic_instaload_union(insta_array)}
421
460
  }
422
461
  ret_hash = insta_array.map{|ar| [ar[:table_name].to_s, []]}.to_h
462
+ opts[:raw] = true
423
463
  ApplicationRecord.headache_sql(name, sql, opts).rows.each{|row|
424
464
  #need to pre-parsed as it has a non-normal output.
425
465
  table_name = row[2]
@@ -433,7 +473,7 @@ module DynamicRecordsMeritfront
433
473
  end
434
474
  alias swiss_instaload_sql dynamic_instaload_sql
435
475
 
436
- def dynamic_attach(instaload_sql_output, base_name, attach_name, base_on: nil, attach_on: nil, one_to_one: false, debug: false)
476
+ def dynamic_attach(instaload_sql_output, base_name, attach_name, base_on: nil, attach_on: nil, one_to_one: false)
437
477
  base_arr = instaload_sql_output[base_name]
438
478
 
439
479
  #return if there is nothing for us to attach to.
@@ -443,14 +483,19 @@ module DynamicRecordsMeritfront
443
483
  # base class information
444
484
  base_class = base_arr.first.class
445
485
  base_class_is_hash = base_class <= Hash
486
+
446
487
  # attach name information for variables
447
488
  attach_name_sym = attach_name.to_sym
448
489
  attach_name_with_at = "@#{attach_name}"
449
490
 
450
491
  #variable accessors and defaults.
451
- base_arr.each{|o|
452
- o.singleton_class.public_send(:attr_accessor, attach_name_sym) unless base_class_is_hash
453
- o.instance_variable_set(attach_name_with_at, []) unless one_to_one
492
+ base_arr.each{ |o|
493
+ unless one_to_one or base_class_is_hash
494
+ o.dynamic ||= OpenStruct.new
495
+ o.dynamic[attach_name_sym] = []
496
+ end
497
+ # o.dynamic o.singleton_class.public_send(:attr_accessor, attach_name_sym) unless base_class_is_hash
498
+ # o.instance_variable_set(attach_name_with_at, []) unless one_to_one
454
499
  }
455
500
 
456
501
  #make sure the attach class has something going on
@@ -505,13 +550,17 @@ module DynamicRecordsMeritfront
505
550
  if base_class_is_hash
506
551
  b[attach_name] = a
507
552
  else
508
- b.instance_variable_set(attach_name_with_at, a)
553
+ b.dynamic ||= OpenStruct.new
554
+ b.dynamic[attach_name] = a
555
+ #b.instance_variable_set(attach_name_with_at, a)
509
556
  end
510
557
  else
511
558
  if base_class_is_hash
512
559
  b[attach_name].push a
513
560
  else
514
- b.instance_variable_get(attach_name_with_at).push a
561
+ # o.dynamic o.single
562
+ b.dynamic[attach_name].push a
563
+ #b.instance_variable_get(attach_name_with_at).push a
515
564
  end
516
565
  end
517
566
  }
@@ -548,7 +597,7 @@ module DynamicRecordsMeritfront
548
597
  record = klass.instantiate(active_record_handled)
549
598
  #set those that were not necessarily expected
550
599
  not_expected = input.slice(*(input.keys - klass.attribute_names))
551
- record.dynamic = not_expected.transform_keys{|k|k.to_sym} if not_expected.keys.any?
600
+ record.dynamic = OpenStruct.new(not_expected.transform_keys{|k|k.to_sym}) if not_expected.keys.any?
552
601
  return record
553
602
  end
554
603
  end
@@ -556,6 +605,8 @@ module DynamicRecordsMeritfront
556
605
  def quick_safe_increment(id, col, val)
557
606
  where(id: id).update_all("#{col} = #{col} + #{val}")
558
607
  end
608
+
609
+
559
610
  end
560
611
 
561
612
  def list_associations
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic-records-meritfront
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Clancy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-24 00:00:00.000000000 Z
11
+ date: 2022-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashid-rails