loggable_activity 0.1.52 → 0.1.53
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/GETTING-STARTED.md +102 -41
- data/README.md +3 -0
- data/docs/LoggableActivity/Activity.html +44 -16
- data/docs/LoggableActivity/Encryption.html +31 -24
- data/docs/LoggableActivity/EncryptionKey.html +10 -7
- data/docs/LoggableActivity/Hooks.html +19 -19
- data/docs/LoggableActivity/Payload.html +7 -7
- data/docs/LoggableActivity/PayloadsBuilder.html +75 -22
- data/docs/LoggableActivity/UpdatePayloadsBuilder.html +66 -67
- data/docs/created.rid +10 -10
- data/docs/js/search_index.js +1 -1
- data/docs/js/search_index.js.gz +0 -0
- data/docs/table_of_contents.html +25 -0
- data/lib/generators/.DS_Store +0 -0
- data/lib/generators/loggable_activity/.DS_Store +0 -0
- data/lib/generators/loggable_activity/install_generator.rb +11 -6
- data/lib/generators/loggable_activity/install_templates_generator.rb +42 -0
- data/lib/generators/loggable_activity/templates/config/locales/loggable_activity.en.yml +36 -0
- data/lib/generators/loggable_activity/templates/helpers/loggable_activity_helper.rb +49 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_create.html.erb +23 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_create.html.slim +18 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_destroy.html.erb +18 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_destroy.html.slim +17 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_show.html.erb +18 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_show.html.slim +17 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_update.html.erb +18 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_update.html.slim +12 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_activity_info.html.erb +12 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_activity_info.html.slim +11 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_list_attrs.html.erb +8 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_list_attrs.html.slim +6 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_update_attrs.html.erb +17 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_update_attrs.html.slim +14 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_updated_relations.html.erb +23 -0
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_updated_relations.html.slim +21 -0
- data/lib/loggable_activity/payloads_builder.rb +3 -19
- data/lib/loggable_activity/update_payloads_builder.rb +18 -60
- data/lib/loggable_activity/version.rb +1 -1
- metadata +34 -15
- /data/lib/generators/loggable_activity/templates/{loggable_activity.yml → config/loggable_activity.yml} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 780e8614a8e5b1c9e97a70a9cb432e8a277d3617dd845fc38b7c41a235b282a9
|
4
|
+
data.tar.gz: fea7bb11d9abcbeeb0423381c4a462df03c07e4ea4487d8e958e9ffe3479ff1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 262803990c60f23a9edcd0484105e0ecac141350d8d4710c5344db7dbe5836587b3959fea74be0890f9abb0e4b0c3a5324f8725d02e3fdd493cbdb3dbcbb53c2
|
7
|
+
data.tar.gz: 1ee1f8eb1850e8150665d9fc65b075c2eac86d7054f6921dee10fd35329e0643e3aa101d416b60278a5695eb8e1b4ef64e3a0ff76e0a13611f31868c31d7d0e2
|
data/CHANGELOG.md
CHANGED
data/GETTING-STARTED.md
CHANGED
@@ -13,20 +13,58 @@ You can try a demo here<br/>
|
|
13
13
|
[https://loggableactivity-efe7b931c886.herokuapp.com/](https://loggableactivity-efe7b931c886.herokuapp.com/)
|
14
14
|
|
15
15
|
## Getting started
|
16
|
-
First we add the loggable_activity gem to the Gemfile `gem 'loggable_activity', '~> x.x.xx'` and then
|
16
|
+
First we add the loggable_activity gem to the Gemfile `gem 'loggable_activity', '~> x.x.xx'` and then<br/>
|
17
|
+
```
|
18
|
+
$ bundle install
|
19
|
+
```
|
17
20
|
Then we have to generate some migrations and additionals files<br/>
|
18
|
-
|
21
|
+
```
|
22
|
+
$ rails generate loggable_activity:install
|
23
|
+
```
|
24
|
+
This will install the following files
|
25
|
+
- app/controllers/concerns/loggable_activity/current_user.rb
|
26
|
+
- config/loggable_activity.yml
|
27
|
+
- config/locales/loggable_activity.en.yml
|
28
|
+
- db/migrate/xxxxxxxxxxxxxx_create_loggable_activities
|
29
|
+
- db/migrate/xxxxxxxxxxxxxx_create_loggable_payloads
|
30
|
+
- db/migrate/xxxxxxxxxxxxxx_create_loggable_encryption_keys
|
31
|
+
|
32
|
+
Then we have to run
|
33
|
+
```
|
34
|
+
$ bundle install
|
35
|
+
```
|
36
|
+
|
37
|
+
## Add hoks to models you want to be logged
|
38
|
+
Include hooks to the model we want to log.
|
39
|
+
|
40
|
+
```
|
41
|
+
class User < ApplicationRecord
|
42
|
+
include LoggableActivity::Hooks
|
43
|
+
```
|
19
44
|
|
20
45
|
## Configuration
|
21
|
-
|
46
|
+
Update `config/application.rb`, you might do it differently in production
|
47
|
+
```
|
48
|
+
config.loggable_activity = ActiveSupport::OrderedOptions.new
|
49
|
+
config.loggable_activity.actor_display_name = :full_name
|
50
|
+
config.loggable_activity.current_user_model_name = 'User'
|
51
|
+
LoggableActivity::Configuration.load_config_file('config/loggable_activity.yaml')
|
52
|
+
```
|
53
|
+
- actor_display_name: this is a method on the User model we want to use when presenting the actor.
|
54
|
+
- current_user_model: This is the name of the model we use for current_user
|
55
|
+
- load_config_file: this is the configuration we will look at next.
|
56
|
+
|
57
|
+
## loggable_activity.yaml
|
58
|
+
You have to update the configuration file installed inside the `config/loggable_activity.yaml`
|
22
59
|
This file defines:
|
23
|
-
- What tables to log
|
24
60
|
- What fields in a table to log
|
25
|
-
-
|
61
|
+
- What relations to include in a logged activity
|
26
62
|
- What should happen to the aggregation if a record is deleted.
|
27
|
-
- What actions to log
|
63
|
+
- What actions to log automatically
|
28
64
|
|
29
|
-
|
65
|
+
**!Catch**<br/>
|
66
|
+
`show` can not `auto_log` so it has to be handled manually, more about that later.<br/>
|
67
|
+
*Here is an example of content for the config/loggable_activity.yaml file*
|
30
68
|
```
|
31
69
|
Demo::Club:
|
32
70
|
record_display_name: name
|
@@ -49,56 +87,79 @@ Lets break this down.
|
|
49
87
|
- `record_display_name:` is the field/method on the on the model we want to display as a headline in the log
|
50
88
|
- Then we can se that we are logging the **name** of the club, in this example that's all there is to log.
|
51
89
|
- Then we can se that we are **logging create, update, and destroy** automatically.
|
52
|
-
- Then there are some relations: that we want to collect and add to the log
|
53
|
-
|
54
|
-
Next we have to include some hooks to the model we want to log.
|
90
|
+
- Then there are some relations: that we want to collect and add to the log.<br/>
|
91
|
+
In this example the club belongs to an addres so we add the street and city from the address to the log.
|
55
92
|
|
56
|
-
```
|
57
|
-
class User < ApplicationRecord
|
58
|
-
include LoggableActivity::Hooks
|
59
|
-
```
|
60
93
|
|
61
|
-
|
94
|
+
## Set current user
|
95
|
+
Add a this to the application_controller.rb
|
62
96
|
```
|
63
97
|
class ApplicationController < ActionController::Base
|
64
98
|
include LoggableActivity::CurrentUser
|
65
99
|
```
|
66
|
-
|
100
|
+
If there is not current_user nothing will be logged. <br/>
|
101
|
+
You can look inside `app/controllers/concerns/current_user.rb` and alter it with a default `current_user` if needed.
|
67
102
|
|
68
|
-
|
103
|
+
## Log the show action
|
104
|
+
As mentioned earlier, show can not be logged automatically<br/>
|
105
|
+
If you want to log the show action you can add this to your controllers show method
|
69
106
|
```
|
70
|
-
|
71
|
-
|
72
|
-
config.loggable_activity.current_user_model_name = 'User'
|
73
|
-
LoggableActivity::Configuration.load_config_file('config/loggable_activity.yaml')
|
107
|
+
def show
|
108
|
+
@user.log(:show)
|
74
109
|
```
|
75
|
-
actor_display_name: this is a method on the User model we want to use when presenting the actor.
|
76
|
-
current_user_model: This is the name of the model we use for current_user
|
77
|
-
load_config_file: this is the configuration file from above.
|
78
|
-
|
79
110
|
|
80
|
-
|
111
|
+
## Relations
|
112
|
+
Supported relations at the moment is
|
113
|
+
- belongs_to
|
114
|
+
- has_one
|
115
|
+
- has_many
|
81
116
|
|
117
|
+
## Render templates
|
118
|
+
*Optional*
|
119
|
+
<br/>You can install all the files needed to render a list of activities<br/>
|
120
|
+
The following command will generate all the files need for showing the activity log
|
82
121
|
```
|
83
|
-
|
84
|
-
include LoggableActivity::Hooks
|
85
|
-
...
|
86
|
-
resto of your code here.
|
87
|
-
|
122
|
+
$ rails g loggable_activity:install_templates
|
88
123
|
```
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
124
|
+
or for the slim template language. (don't run both)
|
125
|
+
```
|
126
|
+
$ rails g loggable_activity:install_templates --template=erb
|
127
|
+
```
|
128
|
+
Now you got the `loggable_activity_helper.rb' installed.<br/>
|
129
|
+
You can use the `render_activity` method from your view like this.
|
130
|
+
```
|
131
|
+
<table>
|
132
|
+
<thead>
|
133
|
+
<tr>
|
134
|
+
<th>Info</th>
|
135
|
+
<th>Attributes</th>
|
136
|
+
<th>Actions</th>
|
137
|
+
</tr>
|
138
|
+
</thead>
|
139
|
+
<tbody>
|
140
|
+
<% @loggable_activities.each do |activity| %>
|
141
|
+
<%= render_activity(activity) %>
|
142
|
+
<% end %>
|
143
|
+
</tbody>
|
144
|
+
</table>
|
145
|
+
```
|
146
|
+
Create a route and a controller and fetch the `@loggable_activities` like this
|
147
|
+
```
|
148
|
+
class ActivityLogsController < ApplicationController
|
149
|
+
def index
|
150
|
+
@loggable_activities = LoggableActivity::Activity.latest(50)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
```
|
154
|
+
Or you can fetch all activities for a given actor like this
|
93
155
|
```
|
94
156
|
def show
|
95
|
-
@
|
157
|
+
@loggable_activities = LoggableActivity::Activity.where(actor: @user)
|
158
|
+
end
|
96
159
|
```
|
97
160
|
|
98
|
-
|
99
|
-
|
100
|
-
## For developers
|
101
|
-
If you want to contribute to the development and try it out in the process
|
161
|
+
## For developers and contributors
|
162
|
+
If you can download and play around with a demo app
|
102
163
|
- 1 Down the demo project from [demo project on github](https://github.com/maxgronlund/LoggableActivityDemoApp)
|
103
164
|
- 2 Update the Gemfile in the demo project so it points to your localhost.
|
104
|
-
- 3 you can now build and test you version of the gem `$ gem build loggable_activity.gemspec`
|
165
|
+
- 3 you can now build and test you version of the gem `$ gem build loggable_activity.gemspec`
|
data/README.md
CHANGED
@@ -27,6 +27,9 @@ Most organizations needs to keep a log of how users interact with data stored in
|
|
27
27
|
Beside the journal in the db, an activity log is kept so it is possible to track how the journal is used.<br/>
|
28
28
|
At some point in time the patients data from the DB and the activity log has to be removed according to GDPR.<br/>
|
29
29
|
|
30
|
+
### Getting started
|
31
|
+
please read the [GETTING-STARTED.md](https://github.com/maxgronlund/LoggableActivity/blob/main/GETTING-STARTED.md) guide
|
32
|
+
|
30
33
|
### Contribute
|
31
34
|
👉 Join the Slack channel here: [LoggableActivity Slack Workspace](https://join.slack.com/t/loggableactivity/shared_invite/zt-2a3tvgv37-mGwjHJTrBXBH2srXFRRSXQ)
|
32
35
|
<br/>
|
@@ -73,6 +73,7 @@
|
|
73
73
|
|
74
74
|
<ul class="link-list" role="directory">
|
75
75
|
<li ><a href="#method-c-activities_for_actor">::activities_for_actor</a>
|
76
|
+
<li ><a href="#method-c-last">::last</a>
|
76
77
|
<li ><a href="#method-c-latest">::latest</a>
|
77
78
|
<li ><a href="#method-i-actor_display_name">#actor_display_name</a>
|
78
79
|
<li ><a href="#method-i-actor_key">#actor_key</a>
|
@@ -129,7 +130,7 @@
|
|
129
130
|
<p>Returns a list of activities for a given actor.</p>
|
130
131
|
|
131
132
|
<div class="method-source-code" id="activities_for_actor-source">
|
132
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
133
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 214</span>
|
133
134
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">activities_for_actor</span>(<span class="ruby-identifier">actor</span>, <span class="ruby-identifier">limit</span> = <span class="ruby-value">20</span>, <span class="ruby-identifier">params</span> = { <span class="ruby-value">offset:</span> <span class="ruby-value">0</span> })
|
134
135
|
<span class="ruby-constant">LoggableActivity</span><span class="ruby-operator">::</span><span class="ruby-constant">Activity</span>.<span class="ruby-identifier">latest</span>(<span class="ruby-identifier">limit</span>, <span class="ruby-identifier">params</span>).<span class="ruby-identifier">where</span>(<span class="ruby-value">actor:</span>)
|
135
136
|
<span class="ruby-keyword">end</span></pre>
|
@@ -137,6 +138,31 @@
|
|
137
138
|
</div>
|
138
139
|
|
139
140
|
|
141
|
+
</div>
|
142
|
+
|
143
|
+
<div id="method-c-last" class="method-detail ">
|
144
|
+
<div class="method-header">
|
145
|
+
<div class="method-heading">
|
146
|
+
<span class="method-name">last</span><span
|
147
|
+
class="method-args">(limit = 1)</span>
|
148
|
+
<span class="method-click-advice">click to toggle source</span>
|
149
|
+
</div>
|
150
|
+
</div>
|
151
|
+
|
152
|
+
<div class="method-description">
|
153
|
+
<p>Returns the last activity.</p>
|
154
|
+
|
155
|
+
<div class="method-source-code" id="last-source">
|
156
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 230</span>
|
157
|
+
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">last</span>(<span class="ruby-identifier">limit</span> = <span class="ruby-value">1</span>)
|
158
|
+
<span class="ruby-keyword">return</span> <span class="ruby-identifier">latest</span>(<span class="ruby-value">1</span>).<span class="ruby-identifier">first</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">limit</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span>
|
159
|
+
|
160
|
+
<span class="ruby-identifier">latest</span>(<span class="ruby-identifier">limit</span>)
|
161
|
+
<span class="ruby-keyword">end</span></pre>
|
162
|
+
</div>
|
163
|
+
</div>
|
164
|
+
|
165
|
+
|
140
166
|
</div>
|
141
167
|
|
142
168
|
<div id="method-c-latest" class="method-detail ">
|
@@ -152,7 +178,7 @@
|
|
152
178
|
<p>Returns a list of activities ordered by creation date.</p>
|
153
179
|
|
154
180
|
<div class="method-source-code" id="latest-source">
|
155
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
181
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 219</span>
|
156
182
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">latest</span>(<span class="ruby-identifier">limit</span> = <span class="ruby-value">20</span>, <span class="ruby-identifier">params</span> = { <span class="ruby-value">offset:</span> <span class="ruby-value">0</span> })
|
157
183
|
<span class="ruby-identifier">offset</span> = <span class="ruby-identifier">params</span>[<span class="ruby-value">:offset</span>] <span class="ruby-operator">||</span> <span class="ruby-value">0</span>
|
158
184
|
<span class="ruby-constant">LoggableActivity</span><span class="ruby-operator">::</span><span class="ruby-constant">Activity</span>
|
@@ -198,7 +224,7 @@
|
|
198
224
|
</pre>
|
199
225
|
|
200
226
|
<div class="method-source-code" id="actor_display_name-source">
|
201
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
227
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 207</span>
|
202
228
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">actor_display_name</span>
|
203
229
|
<span class="ruby-keyword">return</span> <span class="ruby-constant">I18n</span>.<span class="ruby-identifier">t</span>(<span class="ruby-string">'loggable.activity.deleted'</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">encrypted_actor_display_name</span>.<span class="ruby-identifier">nil?</span>
|
204
230
|
|
@@ -270,7 +296,7 @@
|
|
270
296
|
</pre>
|
271
297
|
|
272
298
|
<div class="method-source-code" id="attrs-source">
|
273
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
299
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 68</span>
|
274
300
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">attrs</span>
|
275
301
|
<span class="ruby-identifier">ordered_payloads</span>.<span class="ruby-identifier">map</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">payload</span><span class="ruby-operator">|</span>
|
276
302
|
{
|
@@ -315,7 +341,7 @@
|
|
315
341
|
</pre>
|
316
342
|
|
317
343
|
<div class="method-source-code" id="primary_payload_attrs-source">
|
318
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
344
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 154</span>
|
319
345
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">primary_payload_attrs</span>
|
320
346
|
<span class="ruby-identifier">primary_payload</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">primary_payload</span>.<span class="ruby-identifier">attrs</span> <span class="ruby-operator">:</span> {}
|
321
347
|
<span class="ruby-keyword">end</span></pre>
|
@@ -348,7 +374,7 @@
|
|
348
374
|
</pre>
|
349
375
|
|
350
376
|
<div class="method-source-code" id="record_display_name-source">
|
351
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
377
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 192</span>
|
352
378
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">record_display_name</span>
|
353
379
|
<span class="ruby-keyword">return</span> <span class="ruby-constant">I18n</span>.<span class="ruby-identifier">t</span>(<span class="ruby-string">'loggable.activity.deleted'</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">encrypted_record_display_name</span>.<span class="ruby-identifier">nil?</span>
|
354
380
|
|
@@ -396,7 +422,7 @@
|
|
396
422
|
</pre>
|
397
423
|
|
398
424
|
<div class="method-source-code" id="relations_attrs-source">
|
399
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
425
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 179</span>
|
400
426
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">relations_attrs</span>
|
401
427
|
<span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">filter</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">p</span>[<span class="ruby-value">:payload_type</span>] <span class="ruby-operator">==</span> <span class="ruby-string">'current_association'</span> }
|
402
428
|
<span class="ruby-keyword">end</span></pre>
|
@@ -475,7 +501,7 @@
|
|
475
501
|
</pre>
|
476
502
|
|
477
503
|
<div class="method-source-code" id="update_activity_attrs-source">
|
478
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
504
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 132</span>
|
479
505
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">update_activity_attrs</span>
|
480
506
|
{
|
481
507
|
<span class="ruby-value">update_attrs:</span>,
|
@@ -508,9 +534,10 @@
|
|
508
534
|
|
509
535
|
|
510
536
|
<div class="method-source-code" id="actor_key-source">
|
511
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
537
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 276</span>
|
512
538
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">actor_key</span>
|
513
539
|
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">actor</span>.<span class="ruby-identifier">nil?</span>
|
540
|
+
|
514
541
|
<span class="ruby-constant">LoggableActivity</span><span class="ruby-operator">::</span><span class="ruby-constant">EncryptionKey</span>.<span class="ruby-identifier">for_record</span>(<span class="ruby-identifier">actor</span>)&.<span class="ruby-identifier">key</span>
|
515
542
|
<span class="ruby-keyword">end</span></pre>
|
516
543
|
</div>
|
@@ -532,7 +559,7 @@
|
|
532
559
|
|
533
560
|
|
534
561
|
<div class="method-source-code" id="must_have_at_least_one_payload-source">
|
535
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
562
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 282</span>
|
536
563
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">must_have_at_least_one_payload</span>
|
537
564
|
<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-value">:payloads</span>, <span class="ruby-string">'must have at least one payload'</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">payloads</span>.<span class="ruby-identifier">empty?</span>
|
538
565
|
<span class="ruby-keyword">end</span></pre>
|
@@ -555,7 +582,7 @@
|
|
555
582
|
|
556
583
|
|
557
584
|
<div class="method-source-code" id="ordered_payloads-source">
|
558
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
585
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 266</span>
|
559
586
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">ordered_payloads</span>
|
560
587
|
<span class="ruby-identifier">payloads</span>.<span class="ruby-identifier">order</span>(<span class="ruby-value">:payload_type</span>)
|
561
588
|
<span class="ruby-keyword">end</span></pre>
|
@@ -578,7 +605,7 @@
|
|
578
605
|
|
579
606
|
|
580
607
|
<div class="method-source-code" id="previous_associations_attrs-source">
|
581
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
608
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 262</span>
|
582
609
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">previous_associations_attrs</span>
|
583
610
|
<span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">select</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">p</span>[<span class="ruby-value">:payload_type</span>] <span class="ruby-operator">==</span> <span class="ruby-string">'previous_association'</span> }
|
584
611
|
<span class="ruby-keyword">end</span></pre>
|
@@ -601,7 +628,7 @@
|
|
601
628
|
|
602
629
|
|
603
630
|
<div class="method-source-code" id="primary_payload-source">
|
604
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
631
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 246</span>
|
605
632
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">primary_payload</span>
|
606
633
|
<span class="ruby-identifier">ordered_payloads</span>.<span class="ruby-identifier">find</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">p</span>.<span class="ruby-identifier">payload_type</span> <span class="ruby-operator">==</span> <span class="ruby-string">'primary_payload'</span> }
|
607
634
|
<span class="ruby-keyword">end</span></pre>
|
@@ -624,9 +651,10 @@
|
|
624
651
|
|
625
652
|
|
626
653
|
<div class="method-source-code" id="record_key-source">
|
627
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
654
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 270</span>
|
628
655
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">record_key</span>
|
629
656
|
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">record</span>.<span class="ruby-identifier">nil?</span>
|
657
|
+
|
630
658
|
<span class="ruby-constant">LoggableActivity</span><span class="ruby-operator">::</span><span class="ruby-constant">EncryptionKey</span>.<span class="ruby-identifier">for_record</span>(<span class="ruby-identifier">record</span>)&.<span class="ruby-identifier">key</span>
|
631
659
|
<span class="ruby-keyword">end</span></pre>
|
632
660
|
</div>
|
@@ -648,7 +676,7 @@
|
|
648
676
|
|
649
677
|
|
650
678
|
<div class="method-source-code" id="update_attrs-source">
|
651
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
679
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 238</span>
|
652
680
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">update_attrs</span>
|
653
681
|
<span class="ruby-identifier">update_payload_attrs</span> = <span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">find</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">p</span>[<span class="ruby-value">:payload_type</span>] <span class="ruby-operator">==</span> <span class="ruby-string">'update_payload'</span> }
|
654
682
|
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">update_payload_attrs</span>
|
@@ -675,7 +703,7 @@
|
|
675
703
|
|
676
704
|
|
677
705
|
<div class="method-source-code" id="updated_relations_attrs-source">
|
678
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line
|
706
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/activity.rb, line 250</span>
|
679
707
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">updated_relations_attrs</span>
|
680
708
|
<span class="ruby-identifier">grouped_associations</span> = <span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">group_by</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">p</span>[<span class="ruby-value">:record_class</span>] }
|
681
709
|
|
@@ -110,7 +110,7 @@
|
|
110
110
|
|
111
111
|
|
112
112
|
<div class="method-source-code" id="blank-3F-source">
|
113
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption.rb, line
|
113
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption.rb, line 65</span>
|
114
114
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">blank?</span>(<span class="ruby-identifier">value</span>)
|
115
115
|
<span class="ruby-identifier">value</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-value">:empty?</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">empty?</span> <span class="ruby-operator">:</span> <span class="ruby-operator">!</span><span class="ruby-identifier">value</span>
|
116
116
|
<span class="ruby-keyword">end</span></pre>
|
@@ -124,7 +124,7 @@
|
|
124
124
|
<div class="method-header">
|
125
125
|
<div class="method-heading">
|
126
126
|
<span class="method-name">decrypt</span><span
|
127
|
-
class="method-args">(data,
|
127
|
+
class="method-args">(data, encoded_key)</span>
|
128
128
|
<span class="method-click-advice">click to toggle source</span>
|
129
129
|
</div>
|
130
130
|
</div>
|
@@ -143,20 +143,23 @@
|
|
143
143
|
</pre>
|
144
144
|
|
145
145
|
<div class="method-source-code" id="decrypt-source">
|
146
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption.rb, line
|
147
|
-
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">decrypt</span>(<span class="ruby-identifier">data</span>, <span class="ruby-identifier">
|
148
|
-
<span class="ruby-keyword">return</span> <span class="ruby-string"
|
149
|
-
|
150
|
-
|
151
|
-
<span class="ruby-identifier">
|
152
|
-
|
153
|
-
<span class="ruby-identifier">
|
154
|
-
<span class="ruby-identifier">
|
155
|
-
|
156
|
-
|
157
|
-
<span class="ruby-identifier">
|
146
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption.rb, line 47</span>
|
147
|
+
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">decrypt</span>(<span class="ruby-identifier">data</span>, <span class="ruby-identifier">encoded_key</span>)
|
148
|
+
<span class="ruby-keyword">return</span> <span class="ruby-string">''</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">encoded_key</span>.<span class="ruby-identifier">nil?</span>
|
149
|
+
|
150
|
+
<span class="ruby-identifier">encryption_key</span> = <span class="ruby-constant">Base64</span>.<span class="ruby-identifier">decode64</span>(<span class="ruby-identifier">encoded_key</span>)
|
151
|
+
<span class="ruby-identifier">raise</span> <span class="ruby-constant">EncryptionError</span>, <span class="ruby-string">'Decryption failed: Invalid encryption key length'</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">encryption_key</span>.<span class="ruby-identifier">bytesize</span> <span class="ruby-operator">==</span> <span class="ruby-value">32</span>
|
152
|
+
|
153
|
+
<span class="ruby-identifier">cipher</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Cipher</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">'AES-256-CBC'</span>).<span class="ruby-identifier">decrypt</span>
|
154
|
+
<span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">key</span> = <span class="ruby-identifier">encryption_key</span>
|
155
|
+
|
156
|
+
<span class="ruby-identifier">raw_data</span> = <span class="ruby-constant">Base64</span>.<span class="ruby-identifier">decode64</span>(<span class="ruby-identifier">data</span>)
|
157
|
+
<span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">iv</span> = <span class="ruby-identifier">raw_data</span>[<span class="ruby-value">0</span><span class="ruby-operator">...</span><span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">iv_len</span>] <span class="ruby-comment"># Extract IV from the beginning of raw_data</span>
|
158
|
+
<span class="ruby-identifier">decrypted_data</span> = <span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">update</span>(<span class="ruby-identifier">raw_data</span>[<span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">iv_len</span><span class="ruby-operator">..</span>]) <span class="ruby-operator">+</span> <span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">final</span>
|
159
|
+
|
160
|
+
<span class="ruby-identifier">decrypted_data</span>.<span class="ruby-identifier">force_encoding</span>(<span class="ruby-string">'UTF-8'</span>)
|
158
161
|
<span class="ruby-keyword">rescue</span> <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Cipher</span><span class="ruby-operator">::</span><span class="ruby-constant">CipherError</span> <span class="ruby-operator">=></span> <span class="ruby-identifier">e</span>
|
159
|
-
<span class="ruby-identifier">raise</span> <span class="ruby-constant">EncryptionError</span>, <span class="ruby-
|
162
|
+
<span class="ruby-identifier">raise</span> <span class="ruby-constant">EncryptionError</span>, <span class="ruby-node">"Decryption failed: #{e.message}"</span>
|
160
163
|
<span class="ruby-keyword">end</span></pre>
|
161
164
|
</div>
|
162
165
|
</div>
|
@@ -168,7 +171,7 @@
|
|
168
171
|
<div class="method-header">
|
169
172
|
<div class="method-heading">
|
170
173
|
<span class="method-name">encrypt</span><span
|
171
|
-
class="method-args">(data,
|
174
|
+
class="method-args">(data, encoded_key)</span>
|
172
175
|
<span class="method-click-advice">click to toggle source</span>
|
173
176
|
</div>
|
174
177
|
</div>
|
@@ -188,17 +191,21 @@
|
|
188
191
|
|
189
192
|
<div class="method-source-code" id="encrypt-source">
|
190
193
|
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption.rb, line 22</span>
|
191
|
-
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">encrypt</span>(<span class="ruby-identifier">data</span>, <span class="ruby-identifier">
|
192
|
-
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">nil?</span>
|
193
|
-
|
194
|
-
<span class="ruby-identifier">
|
194
|
+
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">encrypt</span>(<span class="ruby-identifier">data</span>, <span class="ruby-identifier">encoded_key</span>)
|
195
|
+
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">encoded_key</span>.<span class="ruby-identifier">nil?</span>
|
196
|
+
|
197
|
+
<span class="ruby-identifier">encryption_key</span> = <span class="ruby-constant">Base64</span>.<span class="ruby-identifier">decode64</span>(<span class="ruby-identifier">encoded_key</span>)
|
198
|
+
<span class="ruby-identifier">raise</span> <span class="ruby-constant">EncryptionError</span>, <span class="ruby-node">"Encryption failed: Invalid encryption key length #{encryption_key.bytesize}"</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">encryption_key</span>.<span class="ruby-identifier">bytesize</span> <span class="ruby-operator">==</span> <span class="ruby-value">32</span>
|
199
|
+
|
200
|
+
<span class="ruby-identifier">cipher</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Cipher</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">'AES-256-CBC'</span>).<span class="ruby-identifier">encrypt</span>
|
201
|
+
<span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">key</span> = <span class="ruby-identifier">encryption_key</span>
|
202
|
+
<span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">iv</span> = <span class="ruby-identifier">iv</span> = <span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">random_iv</span>
|
195
203
|
|
196
|
-
<span class="ruby-identifier">cipher</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Cipher</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">'AES-128-CBC'</span>).<span class="ruby-identifier">encrypt</span>
|
197
|
-
<span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">key</span> = <span class="ruby-constant">Digest</span><span class="ruby-operator">::</span><span class="ruby-constant">SHA1</span>.<span class="ruby-identifier">hexdigest</span>(<span class="ruby-identifier">encryption_key</span>)[<span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">15</span>]
|
198
204
|
<span class="ruby-identifier">encrypted</span> = <span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">update</span>(<span class="ruby-identifier">data</span>.<span class="ruby-identifier">to_s</span>) <span class="ruby-operator">+</span> <span class="ruby-identifier">cipher</span>.<span class="ruby-identifier">final</span>
|
199
|
-
<span class="ruby-
|
205
|
+
<span class="ruby-comment"># Combine IV with encrypted data, encode with Base64 for storage/transmission</span>
|
206
|
+
<span class="ruby-constant">Base64</span>.<span class="ruby-identifier">encode64</span>(<span class="ruby-identifier">iv</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">encrypted</span>)
|
200
207
|
<span class="ruby-keyword">rescue</span> <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Cipher</span><span class="ruby-operator">::</span><span class="ruby-constant">CipherError</span> <span class="ruby-operator">=></span> <span class="ruby-identifier">e</span>
|
201
|
-
<span class="ruby-identifier">raise</span> <span class="ruby-constant">EncryptionError</span>, <span class="ruby-node">"Encryption failed: #{e.message}
|
208
|
+
<span class="ruby-identifier">raise</span> <span class="ruby-constant">EncryptionError</span>, <span class="ruby-node">"Encryption failed: #{e.message}"</span>
|
202
209
|
<span class="ruby-keyword">end</span></pre>
|
203
210
|
</div>
|
204
211
|
</div>
|
@@ -139,10 +139,10 @@
|
|
139
139
|
</pre>
|
140
140
|
|
141
141
|
<div class="method-source-code" id="create_encryption_key-source">
|
142
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line
|
142
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line 93</span>
|
143
143
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">create_encryption_key</span>(<span class="ruby-identifier">record_type</span>, <span class="ruby-identifier">record_id</span>, <span class="ruby-identifier">parent_key</span> = <span class="ruby-keyword">nil</span>)
|
144
144
|
<span class="ruby-keyword">if</span> <span class="ruby-identifier">parent_key</span>
|
145
|
-
<span class="ruby-identifier">create</span>(<span class="ruby-value">record_type:</span>, <span class="ruby-value">record_id:</span>, <span class="ruby-value">key:</span> <span class="ruby-identifier">random_key</span>, <span class="ruby-value">parent_key:</span>
|
145
|
+
<span class="ruby-identifier">create</span>(<span class="ruby-value">record_type:</span>, <span class="ruby-value">record_id:</span>, <span class="ruby-value">key:</span> <span class="ruby-identifier">random_key</span>, <span class="ruby-value">parent_key:</span>)
|
146
146
|
<span class="ruby-keyword">else</span>
|
147
147
|
<span class="ruby-identifier">create</span>(<span class="ruby-value">record_type:</span>, <span class="ruby-value">record_id:</span>, <span class="ruby-value">key:</span> <span class="ruby-identifier">random_key</span>)
|
148
148
|
<span class="ruby-keyword">end</span>
|
@@ -187,7 +187,7 @@
|
|
187
187
|
</pre>
|
188
188
|
|
189
189
|
<div class="method-source-code" id="for_record-source">
|
190
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line
|
190
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line 67</span>
|
191
191
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">for_record</span>(<span class="ruby-identifier">record</span>, <span class="ruby-identifier">parent_key</span> = <span class="ruby-keyword">nil</span>)
|
192
192
|
<span class="ruby-identifier">encryption_key</span> = <span class="ruby-identifier">find_by</span>(<span class="ruby-value">record:</span>)
|
193
193
|
<span class="ruby-keyword">return</span> <span class="ruby-identifier">encryption_key</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">encryption_key</span>
|
@@ -234,7 +234,7 @@
|
|
234
234
|
</pre>
|
235
235
|
|
236
236
|
<div class="method-source-code" id="for_record_by_type_and_id-source">
|
237
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line
|
237
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line 41</span>
|
238
238
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">for_record_by_type_and_id</span>(<span class="ruby-identifier">record_type</span>, <span class="ruby-identifier">record_id</span>, <span class="ruby-identifier">parent_key</span> = <span class="ruby-keyword">nil</span>)
|
239
239
|
<span class="ruby-identifier">encryption_key</span> = <span class="ruby-identifier">find_by</span>(<span class="ruby-value">record_type:</span>, <span class="ruby-value">record_id:</span>)
|
240
240
|
<span class="ruby-keyword">return</span> <span class="ruby-identifier">encryption_key</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">encryption_key</span>
|
@@ -272,9 +272,12 @@
|
|
272
272
|
</pre>
|
273
273
|
|
274
274
|
<div class="method-source-code" id="random_key-source">
|
275
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line
|
275
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line 111</span>
|
276
276
|
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">random_key</span>
|
277
|
-
<span class="ruby-
|
277
|
+
<span class="ruby-comment"># Generate 32 random bytes (256 bits) directly</span>
|
278
|
+
<span class="ruby-identifier">encryption_key</span> = <span class="ruby-constant">SecureRandom</span>.<span class="ruby-identifier">random_bytes</span>(<span class="ruby-value">32</span>)
|
279
|
+
<span class="ruby-comment"># Encode the key in Base64 to ensure it's in a transferable format</span>
|
280
|
+
<span class="ruby-constant">Base64</span>.<span class="ruby-identifier">encode64</span>(<span class="ruby-identifier">encryption_key</span>).<span class="ruby-identifier">strip</span>
|
278
281
|
<span class="ruby-keyword">end</span></pre>
|
279
282
|
</div>
|
280
283
|
</div>
|
@@ -302,7 +305,7 @@
|
|
302
305
|
<p>Marks the encryption key as deleted by updating the key to nil.</p>
|
303
306
|
|
304
307
|
<div class="method-source-code" id="mark_as_deleted-source">
|
305
|
-
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line
|
308
|
+
<pre><span class="ruby-comment"># File lib/loggable_activity/encryption_key.rb, line 17</span>
|
306
309
|
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">mark_as_deleted</span>
|
307
310
|
<span class="ruby-identifier">update</span>(<span class="ruby-value">key:</span> <span class="ruby-keyword">nil</span>)
|
308
311
|
<span class="ruby-identifier">parent_key</span>.<span class="ruby-identifier">mark_as_deleted</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">parent_key</span>.<span class="ruby-identifier">present?</span>
|