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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +28 -103
- data/lib/dynamic-records-meritfront/version.rb +1 -1
- data/lib/dynamic-records-meritfront.rb +45 -66
- 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: 0145c6915704e699ab557a6e45348a1555a774e79f4a49925be7f41d88877a6d
|
4
|
+
data.tar.gz: ebed51c113a9f94b9f4bc481069da98b8771c5b6aa24af2403b9a1283869fed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc6978059ea84ee5584a967bbf0c465ebd81fdaee751dd94c745811f2704216b5992d433ed4168f67187fd18e485d586ca220cc468e617b93da3798e5ed8b475
|
7
|
+
data.tar.gz: 6efa88c7bb6f60789301660d77d874b2252fd69fe0b4de66d223d1df863df9518dce2c89bd60d6f6a30ff167535d7adf9392ea9320979a59780a2b9e130737d7
|
data/Gemfile.lock
CHANGED
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 #
|
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.
|
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
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
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.
|
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
|
283
|
-
- attach_on: put a proc here to override the matching
|
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.
|
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']
|
299
|
+
pp out['limited_users']
|
298
300
|
|
299
301
|
```
|
300
302
|
|
301
303
|
printed output:
|
302
304
|
```ruby
|
303
|
-
[
|
304
|
-
|
305
|
-
|
306
|
-
|
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>
|
@@ -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
|
-
|
70
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
-
|
496
|
-
|
497
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
600
|
-
|
601
|
-
|
602
|
-
#
|
603
|
-
|
604
|
-
|
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.
|
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-
|
11
|
+
date: 2022-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashid-rails
|