dynamic-records-meritfront 2.0.3 → 2.0.7
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 +168 -18
- data/lib/dynamic-records-meritfront/version.rb +1 -1
- data/lib/dynamic-records-meritfront.rb +60 -9
- 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: 128f27b863756504bd22fec97e8db725deaca0456a3c93a21fa0748e40d76b6e
|
4
|
+
data.tar.gz: 6322c4ac157d8dcacc79a993ad68c850b9c637c0d15ad25f3a384977c986519c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4266bd61b7a40f34cecb1e6cf2ba954962bdd2a1565a0a64e865931b5f46b477b5303850d1dbc28a7fb8fe7fce4eea4d6f5f74c836111a80c6ba7b0d5670bd76
|
7
|
+
data.tar.gz: ec0b58b6bd7ab37a3798d994d23df9081a12a41ce4e1e2c5eb05f6289f456fbcf74473e4b618598762ad04bd970c22c611833f186ac05425b4d715776277de1c
|
data/Gemfile.lock
CHANGED
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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).
|
@@ -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
|
-
# -
|
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
|
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
|
-
|
453
|
-
|
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.
|
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
|
-
|
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.
|
4
|
+
version: 2.0.7
|
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-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashid-rails
|