dynamic-records-meritfront 2.0.17 → 2.0.21

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: 122854ead22d0622151522249d115b088dc1ecd4d21fe9a794a23126ab105d65
4
- data.tar.gz: 216371aab9c74e6a9a0c3638d0436cfc0f83e72f7668c7c57a3f73dc20876c19
3
+ metadata.gz: 0145c6915704e699ab557a6e45348a1555a774e79f4a49925be7f41d88877a6d
4
+ data.tar.gz: ebed51c113a9f94b9f4bc481069da98b8771c5b6aa24af2403b9a1283869fed2
5
5
  SHA512:
6
- metadata.gz: d4d2ab247cf4cff13fad1f772cc437585aeb28a59686b4ff0046a7bffd2466c944749c1ab22fdc058b02150043d4e05515e0d5b5d962c78b84c02d9b8985618f
7
- data.tar.gz: 6f962c2213eedc0441a38002e5ce5770ec932e6ee0c36faa2ff9c965abfa56502ad8e56accade17d94216b8c6025883e6276f65515d6886aa09681ec11f713e4
6
+ metadata.gz: cc6978059ea84ee5584a967bbf0c465ebd81fdaee751dd94c745811f2704216b5992d433ed4168f67187fd18e485d586ca220cc468e617b93da3798e5ed8b475
7
+ data.tar.gz: 6efa88c7bb6f60789301660d77d874b2252fd69fe0b4de66d223d1df863df9518dce2c89bd60d6f6a30ff167535d7adf9392ea9320979a59780a2b9e130737d7
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamic-records-meritfront (2.0.17)
4
+ dynamic-records-meritfront (2.0.21)
5
5
  hashid-rails
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -135,16 +135,12 @@ This is an example of why this method is good for dynamic prepared statements.
135
135
  SELECT id FROM votes LIMIT 1
136
136
  }).first
137
137
  v.inspect # "#<Vote id: 696969>"
138
- v.dynamic # nil
139
138
 
140
139
  #get a cool test vote. Note that is_this_vote_cool is not on the vote table.
141
140
  test = Vote.dynamic_sql('test', %Q{
142
141
  SELECT id, 'yes' AS is_this_vote_cool FROM votes LIMIT 1
143
142
  }).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. Implementation issues are to do with the fact that ActiveRecord::Base doesn't expect database columns to change randomly, and doesn't allow us to append to the attributes accessor.
145
- test.dynamic # <OpenStruct is_this_vote_cool='yes'>
146
- test.dynamic.is_this_vote_cool # "yes"
147
- test.dynamic[:is_this_vote_cool] #yes
143
+ test.inspect # #<Vote id: 696969, is_this_vote_cool: "yes"> #getting attributes added dynamically to the models, and also showing up on inspects, was... more difficult than i anticipated.
148
144
  ```
149
145
  </details>
150
146
 
@@ -221,7 +217,7 @@ Preload :votes on some comments. :votes is an active record has_many relation.
221
217
 
222
218
  ```ruby
223
219
  # the ruby entered
224
- output = ApplicationRecord.swiss_instaload_sql('test', [
220
+ output = ApplicationRecord.dynamic_instaload_sql('test', [
225
221
  User.instaload('SELECT id FROM users WHERE users.id = ANY (:user_ids) AND users.created_at > :time', table_name: 'limited_users', relied_on: true),
226
222
  User.instaload(%Q{
227
223
  SELECT friends.smaller_user_id AS id, friends.bigger_user_id AS friended_to
@@ -261,26 +257,32 @@ the sql:
261
257
 
262
258
  the output:
263
259
  ```ruby
264
- {
265
- "limited_users"=>[#<User id: 3>, #<User id: 1>, #<User id: 4>],
266
- "users_friends"=>[
267
- #<User id: 21>,
268
- #<User id: 5>,
269
- ...],
270
- "users_follows"=> [
271
- {"followable_id"=>22, "follower_id"=>4},
272
- {"followable_id"=>23, "follower_id"=>4}, ...]
273
- }
260
+ {"limited_users"=>
261
+ [#<User id: 3>,
262
+ #<User id: 14>,
263
+ #<User id: 9>,
264
+ ...],
265
+ "users_friends"=>
266
+ [#<User id: 9, friended_to: 14>,
267
+ #<User id: 21, friended_to: 14>,
268
+ #<User id: 14, friended_to: 9>,
269
+ ...],
270
+ "users_follows"=>
271
+ [{"followable_id"=>931, "follower_id"=>23},
272
+ {"followable_id"=>932, "follower_id"=>23},
273
+ {"followable_id"=>935, "follower_id"=>19},
274
+ ...]}
275
+
276
+
274
277
  ```
275
278
  </details>
276
279
 
277
280
  #### self.dynamic_attach(instaload_sql_output, base_name, attach_name, base_on: nil, attach_on: nil, one_to_one: false)
278
- 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.
279
- - instaload_sql_output: output of above dynamic_instaload_sql
281
+ taking the output of the dynamic_instaload_sql, this method attaches the models together so they have relations.
280
282
  - base_name: the name of the table we will be attaching to
281
283
  - attach_name: the name of the table that will be attached
282
- - base_on: put a proc here to override the matching behavior on the base table. Default is {|user| user.id}
283
- - attach_on: put a proc here to override the matching behavior on the attach table. Default is {|post| post.user_id}
284
+ - base_on: put a proc here to override the matching key for the base table. Default is, for a user and post type, {|user| user.id}
285
+ - attach_on: put a proc here to override the matching key for the attach table. Default is, for a user and post type, {|post| post.user_id}
284
286
  - one_to_one: switches between a one-to-one relationship or not
285
287
 
286
288
  <details>
@@ -289,98 +291,21 @@ taking the output of the dynamic_instaload_sql, this method attaches the models
289
291
  ```ruby
290
292
 
291
293
  ApplicationRecord.dynamic_attach(out, 'limited_users', 'users_friends', attach_on: Proc.new {|users_friend|
292
- users_friend.dynamic[:friended_to]
294
+ users_friend.friended_to
293
295
  })
294
296
  ApplicationRecord.dynamic_attach(out, 'limited_users', 'users_follows', attach_on: Proc.new {|follow|
295
297
  follow['follower_id']
296
298
  })
297
- pp out['limited_users'].map{|o| {id: o.id, users_friends: o.dynamic.users_friends.first(4), users_follows: o.dynamic.users_follows.first(4)}}
299
+ pp out['limited_users']
298
300
 
299
301
  ```
300
302
 
301
303
  printed output:
302
304
  ```ruby
303
- [{:id=>3,
304
- :users_friends=>[#<User id: 21>, #<User id: 5>, #<User id: 6>],
305
- :users_follows=>
306
- [{"followable_id"=>935, "follower_id"=>3},
307
- {"followable_id"=>938, "follower_id"=>3},
308
- {"followable_id"=>939, "follower_id"=>3},
309
- {"followable_id"=>932, "follower_id"=>3}]},
310
- {:id=>14,
311
- :users_friends=>
312
- [#<User id: 18>, #<User id: 9>, #<User id: 21>, #<User id: 5>],
313
- :users_follows=>
314
- [{"followable_id"=>936, "follower_id"=>14},
315
- {"followable_id"=>937, "follower_id"=>14},
316
- {"followable_id"=>938, "follower_id"=>14},
317
- {"followable_id"=>939, "follower_id"=>14}]},
318
- {:id=>9,
319
- :users_friends=>
320
- [#<User id: 19>, #<User id: 15>, #<User id: 14>, #<User id: 7>],
321
- :users_follows=>
322
- [{"followable_id"=>938, "follower_id"=>9},
323
- {"followable_id"=>937, "follower_id"=>9},
324
- {"followable_id"=>932, "follower_id"=>9},
325
- {"followable_id"=>933, "follower_id"=>9}]}, ... ]
326
-
327
- ```
328
-
329
- </details>
330
-
331
- #### dynamic_print(v, print: true)
332
- - prints models along with dynamic variables using the pretty-printer. Fails in production to prevent leaking sensative information.
333
- - The reason this exists is that I could not override the inspect method for ActiveRecord. In my case, devise then overrode it from me. A little annoying. Because of that, this is now the best way to view both attributes and dynamic variables in the same location.
334
-
335
- <details>
336
- <summary> example using output of dynamic_attach example </summary>
337
-
338
- ```ruby
339
- ApplicationRecord.dynamic_print(out['limited_users'])
340
- ```
341
-
342
- printed output:
343
- ```ruby
344
- [#<struct DynamicRecordsMeritfront::RecordForPrint
345
- class="User",
346
- attributes={"id"=>3},
347
- dynamic=
348
- {:users_friends=>
349
- [#<struct DynamicRecordsMeritfront::RecordForPrint
350
- class="User",
351
- attributes={"id"=>5},
352
- dynamic={:friended_to=>3}>,
353
- #<struct DynamicRecordsMeritfront::RecordForPrint
354
- class="User",
355
- attributes={"id"=>6},
356
- dynamic={:friended_to=>3}>,
357
- #<struct DynamicRecordsMeritfront::RecordForPrint
358
- class="User",
359
- attributes={"id"=>21},
360
- dynamic={:friended_to=>3}>],
361
- :users_follows=>
362
- [{"followable_id"=>935, "follower_id"=>3},
363
- {"followable_id"=>938, "follower_id"=>3},
364
- {"followable_id"=>939, "follower_id"=>3},
365
- {"followable_id"=>932, "follower_id"=>3},
366
- {"followable_id"=>5, "follower_id"=>3},
367
- {"followable_id"=>4, "follower_id"=>3},
368
- {"followable_id"=>23, "follower_id"=>3},
369
- {"followable_id"=>22, "follower_id"=>3},
370
- {"followable_id"=>15, "follower_id"=>3},
371
- {"followable_id"=>6, "follower_id"=>3},
372
- {"followable_id"=>3, "follower_id"=>3},
373
- {"followable_id"=>8, "follower_id"=>3},
374
- {"followable_id"=>7, "follower_id"=>3},
375
- {"followable_id"=>1, "follower_id"=>3},
376
- {"followable_id"=>18, "follower_id"=>3},
377
- {"followable_id"=>16, "follower_id"=>3},
378
- {"followable_id"=>21, "follower_id"=>3},
379
- {"followable_id"=>9, "follower_id"=>3},
380
- {"followable_id"=>19, "follower_id"=>3}]}>,
381
-
382
- ...
383
-
305
+ #<User id: 3, users_friends: [#<User id: 5, friended_to: 3>, #<User id: 6, friended_to: 3>, #<User id: 21, friended_to: 3>], users_follows: [{"followable_id"=>935, "follower_id"=>3}, {"followable_id"=>938, "follower_id"=>3}, ...]>,
306
+ #<User id: 14, users_friends: [#<User id: 9, friended_to: 14>, #<User id: 21, friended_to: 14>, ...], users_follows: [{"followable_id"=>936, "follower_id"=>14}, {"followable_id"=>937, "follower_id"=>14}, {"followable_id"=>938, "follower_id"=>14}, ...]>,
307
+ #<User id: 9, users_friends: [#<User id: 14, friended_to: 9>, #<User id: 22, friended_to: 9>, ...], users_follows: [{"followable_id"=>938, "follower_id"=>9}, {"followable_id"=>937, "follower_id"=>9}, ...]>,
308
+ #<User id: 19, users_friends: [#<User id: 1, friended_to: 19>, #<User id: 18, friended_to: 19>, ...], users_follows: [{"followable_id"=>935, "follower_id"=>19}, {"followable_id"=>936, "follower_id"=>19}, {"followable_id"=>938, "follower_id"=>19}, ...]>,
384
309
  ```
385
310
 
386
311
  </details>
@@ -1,5 +1,5 @@
1
1
 
2
2
  module DynamicRecordsMeritfront
3
- VERSION = '2.0.17'
3
+ VERSION = '2.0.21'
4
4
  end
5
5
  #this file gets overwritten automatically on minor updates, major ones need to be manually changed
@@ -19,7 +19,6 @@ module DynamicRecordsMeritfront
19
19
  #Note we defined here as it breaks early on as Rails.application returns nil
20
20
  PROJECT_NAME = Rails.application.class.to_s.split("::").first.to_s.downcase
21
21
  DYNAMIC_SQL_RAW = true
22
- attr_accessor :dynamic
23
22
  end
24
23
 
25
24
  class MultiRowExpression
@@ -66,47 +65,33 @@ module DynamicRecordsMeritfront
66
65
  end
67
66
  end
68
67
 
69
- RecordForPrint = Struct.new(:class, :attributes, :dynamic)
70
- module ClassMethods
71
-
72
- def dynamic_print_h(v)
73
- v = v.dup
74
- return v.to_h.transform_values{|x|
75
- dynamic_print(x, print: false)
76
- }
77
- end
68
+ def questionable_attribute_set(atr, value)
69
+ #this is needed on initalization of a new variable after the actual thing has been made already.
78
70
 
79
- def dynamic_print_arr(v)
80
- v = v.dup
81
- return v.map{|x|
82
- dynamic_print(x, print: false)
83
- }
84
- end
71
+ #set a bunk type of the generic value type
72
+ @attributes.instance_variable_get(:@types)[atr] = ActiveModel::Type::Value.new
73
+ #Set it
74
+ self[atr] = value
75
+ end
85
76
 
86
- def dynamic_print_obj(v)
87
- if v.class < ActiveRecord::Base
88
- #return v.dynamic
89
- return RecordForPrint.new(v.class.to_s, v.attributes, dynamic_print(v.dynamic, print: false))
90
- else
91
- v
77
+ def inspect
78
+ #basically the same as the upstream active record function (as of october 25 2022 on AR V7.0.4)
79
+ #except that I changed self.class.attribute_names -> self.attribute_names to pick up our
80
+ #dynamic insanity. Was this a good idea? Well I guess its better than not doing it
81
+ inspection = if defined?(@attributes) && @attributes
82
+ self.attribute_names.filter_map do |name|
83
+ if _has_attribute?(name)
84
+ "#{name}: #{attribute_for_inspect(name)}"
92
85
  end
86
+ end.join(", ")
87
+ else
88
+ "not initialized"
93
89
  end
94
90
 
95
- def dynamic_print(v, print: true)
96
- return if Rails.env.production?
97
- if v.class == Hash || v.class == OpenStruct
98
- ret = dynamic_print_h v
99
- elsif v.class == Array
100
- ret = dynamic_print_arr v
101
- else
102
- ret = dynamic_print_obj v
103
- end
104
- if print
105
- pp ret
106
- else
107
- return ret
108
- end
109
- end
91
+ "#<#{self.class} #{inspection}>"
92
+ end
93
+
94
+ module ClassMethods
110
95
 
111
96
  def has_run_migration?(nm)
112
97
  #put in a string name of the class and it will say if it has allready run the migration.
@@ -475,6 +460,8 @@ module DynamicRecordsMeritfront
475
460
  end
476
461
  alias swiss_instaload_sql dynamic_instaload_sql
477
462
 
463
+
464
+
478
465
  def dynamic_attach(instaload_sql_output, base_name, attach_name, base_on: nil, attach_on: nil, one_to_one: false)
479
466
  base_arr = instaload_sql_output[base_name]
480
467
 
@@ -486,15 +473,20 @@ module DynamicRecordsMeritfront
486
473
  base_class = base_arr.first.class
487
474
  base_class_is_hash = base_class <= Hash
488
475
 
489
- # attach name information for variables
490
- attach_name_sym = attach_name.to_sym
491
- attach_name_with_at = "@#{attach_name}"
492
476
 
493
477
  #variable accessors and defaults.
494
478
  base_arr.each{ |o|
495
- unless one_to_one or base_class_is_hash
496
- o.dynamic ||= OpenStruct.new
497
- o.dynamic[attach_name_sym] = []
479
+ #
480
+ # there is no way to set an attribute after instantiation I tried I looked
481
+ # I dealt with silent breaks on symbol keys, I have wasted time, its fine.
482
+
483
+ if not base_class_is_hash
484
+ if one_to_one
485
+ #attach name must be a string
486
+ o.questionable_attribute_set(attach_name, nil)
487
+ else
488
+ o.questionable_attribute_set(attach_name, [])
489
+ end
498
490
  end
499
491
  # o.dynamic o.singleton_class.public_send(:attr_accessor, attach_name_sym) unless base_class_is_hash
500
492
  # o.instance_variable_set(attach_name_with_at, []) unless one_to_one
@@ -531,9 +523,7 @@ module DynamicRecordsMeritfront
531
523
  attach_on = Proc.new{|x| x[default_attach_col]}
532
524
  else
533
525
  attach_on = Proc.new{|x|
534
- ret = x.attributes[default_attach_col]
535
- ret ||= x.dynamic[default_attach_col]
536
- ret
526
+ x.attributes[default_attach_col]
537
527
  }
538
528
  end
539
529
  end
@@ -551,21 +541,9 @@ module DynamicRecordsMeritfront
551
541
  #(b=base, a=attach)
552
542
  add_to_base = Proc.new{|b, a|
553
543
  if one_to_one
554
- if base_class_is_hash
555
- b[attach_name] = a
556
- else
557
- b.dynamic ||= OpenStruct.new
558
- b.dynamic[attach_name] = a
559
- #b.instance_variable_set(attach_name_with_at, a)
560
- end
544
+ b[attach_name] = a
561
545
  else
562
- if base_class_is_hash
563
- b[attach_name].push a
564
- else
565
- # o.dynamic o.single
566
- b.dynamic[attach_name].push a
567
- #b.instance_variable_get(attach_name_with_at).push a
568
- end
546
+ b[attach_name].push a
569
547
  end
570
548
  }
571
549
 
@@ -596,12 +574,13 @@ module DynamicRecordsMeritfront
596
574
  if klass.abstract_class
597
575
  return input
598
576
  else
599
- #handle attributes through ar if allowed. Throws an error on unkown variables, except apparently for devise classes? 😡
600
- active_record_handled = input.slice(*(klass.attribute_names & input.keys))
601
- record = klass.instantiate(active_record_handled)
602
- #set those that were not necessarily expected
603
- not_expected = input.slice(*(input.keys - klass.attribute_names))
604
- record.dynamic = OpenStruct.new(not_expected.transform_keys{|k|k.to_sym}) if not_expected.keys.any?
577
+ record = klass.instantiate(input.stringify_keys ) #trust me they need to be stringified
578
+ # #handle attributes through ar if allowed. Throws an error on unkown variables, except apparently for devise classes? 😡
579
+ # active_record_handled = input.slice(*(klass.attribute_names & input.keys))
580
+ # record = klass.instantiate(active_record_handled)
581
+ # #set those that were not necessarily expected
582
+ # not_expected = input.slice(*(input.keys - klass.attribute_names))
583
+ # record.dynamic = OpenStruct.new(not_expected.transform_keys{|k|k.to_sym}) if not_expected.keys.any?
605
584
  return record
606
585
  end
607
586
  end
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.17
4
+ version: 2.0.21
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-25 00:00:00.000000000 Z
11
+ date: 2022-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashid-rails