table_sync 6.0.4 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/.rubocop.yml +12 -1
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +152 -138
- data/README.md +1 -7
- data/lib/table_sync/errors.rb +3 -2
- data/lib/table_sync/instrument.rb +24 -2
- data/lib/table_sync/orm_adapter/active_record.rb +4 -4
- data/lib/table_sync/orm_adapter/base.rb +6 -4
- data/lib/table_sync/orm_adapter/sequel.rb +6 -6
- data/lib/table_sync/publishing/data/raw.rb +9 -5
- data/lib/table_sync/publishing/message/raw.rb +8 -9
- data/lib/table_sync/publishing/params/raw.rb +3 -1
- data/lib/table_sync/publishing/raw.rb +3 -1
- data/lib/table_sync/receiving/config.rb +2 -2
- data/lib/table_sync/receiving/handler.rb +3 -3
- data/lib/table_sync/receiving/model/active_record.rb +2 -2
- data/lib/table_sync/receiving/model/sequel.rb +1 -1
- data/lib/table_sync/setup/active_record.rb +1 -1
- data/lib/table_sync/setup/base.rb +1 -1
- data/lib/table_sync/setup/sequel.rb +1 -1
- data/lib/table_sync/version.rb +1 -1
- data/lib/table_sync.rb +12 -1
- data/table_sync.gemspec +1 -1
- metadata +4 -11
- data/docs/message_protocol.md +0 -24
- data/docs/notifications.md +0 -45
- data/docs/publishing/configuration.md +0 -143
- data/docs/publishing/manual.md +0 -155
- data/docs/publishing/publishers.md +0 -162
- data/docs/publishing.md +0 -80
- data/docs/receiving.md +0 -346
@@ -1,162 +0,0 @@
|
|
1
|
-
# Publishers
|
2
|
-
|
3
|
-
There are three publishers you can use to send data.
|
4
|
-
|
5
|
-
- `TableSync::Publishing::Single` - sends one row with initialization.
|
6
|
-
- `TableSync::Publishing::Batch` - sends a batch of rows with initialization.
|
7
|
-
- `TableSync::Publishing::Raw` - sends raw data without checks.
|
8
|
-
|
9
|
-
## Single
|
10
|
-
|
11
|
-
`TableSync::Publishing::Single` - sends one row with initialization.
|
12
|
-
|
13
|
-
This is a publisher called by `TableSync.sync(self)`.
|
14
|
-
|
15
|
-
### Expected parameters:
|
16
|
-
|
17
|
-
- `object_class` - class (model) used to initialize published object
|
18
|
-
- `original_attributes` - attributes used to initialize `object_class` with
|
19
|
-
- `debounce_time` - minimum allowed time between delayed publishings
|
20
|
-
- `event` - type of event that happened to the published object (`create`, `update`, `destroy`); `update` by default
|
21
|
-
|
22
|
-
### What it does (when uses `#publish_now`):
|
23
|
-
- takes in the `original_attributes`, `object_class`, `event`
|
24
|
-
- constantizes `object_class`
|
25
|
-
- extracts the primary key (`needle`) of the `object_class` from the `original_attributes`
|
26
|
-
- queries the database for the object with the `needle` (for `update` and `create`) or initializes the `object_class` with `original_attributes` (for `destroy`)
|
27
|
-
- constructs routing_key using `routing_key_callable` and `#attributes_for_routing_key` (if defined)
|
28
|
-
- constructs headers using `headers_callable` and `#attributes_for_headers` (if defined)
|
29
|
-
- publishes Rabbit message (uses attributes from queried/initialized object as data)
|
30
|
-
- sends notification (if set up)
|
31
|
-
|
32
|
-
### What it does (when uses `#publish_later`):
|
33
|
-
- takes in the `original_attributes`, `object_class`, `debounce_time`, `event`
|
34
|
-
- serializes the `original_attributes`, silently filters out unserializable keys/values
|
35
|
-
- enqueues (or skips) the job with the `serialized_original_attributes` to be performed in time according to debounce
|
36
|
-
- job (if enqueued) calls `TableSync::Publishing::Single#publish_now` with `serialized_original_attributes` and the same `object_class`, `debounce_time`, `event`
|
37
|
-
|
38
|
-
### Serialization
|
39
|
-
|
40
|
-
Currently allowed key/values are:
|
41
|
-
`NilClass`, `String`, `TrueClass`, `FalseClass`, `Numeric`, `Symbol`.
|
42
|
-
|
43
|
-
### Job
|
44
|
-
|
45
|
-
Job is defined in `TableSync.single_publishing_job_class_callable` as a proc. Read more in [Configuration](docs/publishing/configuration.md).
|
46
|
-
|
47
|
-
### Example #1 (send right now)
|
48
|
-
|
49
|
-
```ruby
|
50
|
-
TableSync::Publishing::Single.new(
|
51
|
-
object_class: "User",
|
52
|
-
original_attributes: { id: 1, name: "Mark" },
|
53
|
-
debounce_time: 60, # useless for #publish _now, can be skipped
|
54
|
-
event: :create,
|
55
|
-
).publish_now
|
56
|
-
```
|
57
|
-
|
58
|
-
### Example #2 (enqueue job)
|
59
|
-
|
60
|
-
```ruby
|
61
|
-
TableSync::Publishing::Single.new(
|
62
|
-
object_class: "User",
|
63
|
-
original_attributes: { id: 1, name: "Mark" }, # will be serialized!
|
64
|
-
debounce_time: 60,
|
65
|
-
event: :update,
|
66
|
-
).publish_later
|
67
|
-
```
|
68
|
-
|
69
|
-
## Batch
|
70
|
-
|
71
|
-
- `TableSync::Publishing::Batch` - sends a batch of rows with initialization.
|
72
|
-
|
73
|
-
### Expected parameters:
|
74
|
-
|
75
|
-
- `object_class` - class (model) used to initialize published objects
|
76
|
-
- `original_attributes` - array of attributes used to initialize `object_class` with
|
77
|
-
- `event` - type of event that happened to the published objects (`create`, `update`, `destroy`); `update` by default
|
78
|
-
- `routing_key` - custom routing_key
|
79
|
-
- `headers` - custom headers
|
80
|
-
|
81
|
-
### What it does (when uses `#publish_now`):
|
82
|
-
- takes in the `original_attributes`, `object_class`, `event`, `routing_key`, `headers`
|
83
|
-
- constantizes `object_class`
|
84
|
-
- extracts primary keys (`needles`) of the `object_class` from the array of `original_attributes`
|
85
|
-
- queries the database for the objects with `needles` (for `update` and `create`) or initializes the `object_class` with `original_attributes` (for `destroy`)
|
86
|
-
- constructs routing_key using `routing_key_callable` (ignores `#attributes_for_routing_key`) or uses `routing_key` if given
|
87
|
-
- constructs headers using `headers_callable` (ignores `#attributes_for_headers`) or uses `headers` if given
|
88
|
-
- publishes Rabbit message (uses attributes from queried/initialized objects as data)
|
89
|
-
- sends notification (if set up)
|
90
|
-
|
91
|
-
### What it does (when uses `#publish_later`):
|
92
|
-
- takes in the `original_attributes`, `object_class`, `event`, `routing_key`, `headers`
|
93
|
-
- serializes the array of `original_attributes`, silently filters out unserializable keys/values
|
94
|
-
- enqueues the job with the `serialized_original_attributes`
|
95
|
-
- job calls `TableSync::Publishing::Batch#publish_now` with `serialized_original_attributes` and the same `object_class`, `event`, `routing_key`, `headers`
|
96
|
-
|
97
|
-
### Serialization
|
98
|
-
|
99
|
-
Currently allowed key/values are:
|
100
|
-
`NilClass`, `String`, `TrueClass`, `FalseClass`, `Numeric`, `Symbol`.
|
101
|
-
|
102
|
-
### Job
|
103
|
-
|
104
|
-
Job is defined in `TableSync.batch_publishing_job_class_callable` as a proc. Read more in [Configuration](docs/publishing/configuration.md).
|
105
|
-
|
106
|
-
### Example #1 (send right now)
|
107
|
-
|
108
|
-
```ruby
|
109
|
-
TableSync::Publishing::Batch.new(
|
110
|
-
object_class: "User",
|
111
|
-
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }],
|
112
|
-
event: :create,
|
113
|
-
routing_key: :custom_key, # optional
|
114
|
-
headers: { type: "admin" }, # optional
|
115
|
-
).publish_now
|
116
|
-
```
|
117
|
-
|
118
|
-
### Example #2 (enqueue job)
|
119
|
-
|
120
|
-
```ruby
|
121
|
-
TableSync::Publishing::Batch.new(
|
122
|
-
object_class: "User",
|
123
|
-
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }],
|
124
|
-
event: :create,
|
125
|
-
routing_key: :custom_key, # optional
|
126
|
-
headers: { type: "admin" }, # optional
|
127
|
-
).publish_later
|
128
|
-
```
|
129
|
-
|
130
|
-
## Raw
|
131
|
-
- `TableSync::Publishing::Raw` - sends raw data without checks.
|
132
|
-
|
133
|
-
Be carefull with this publisher. There are no checks for the data sent.
|
134
|
-
You can send anything.
|
135
|
-
|
136
|
-
### Expected parameters:
|
137
|
-
|
138
|
-
- `object_class` - model
|
139
|
-
- `original_attributes` - raw data that will be sent
|
140
|
-
- `event` - type of event that happened to the published objects (`create`, `update`, `destroy`); `update` by default
|
141
|
-
- `routing_key` - custom routing_key
|
142
|
-
- `headers` - custom headers
|
143
|
-
|
144
|
-
### What it does (when uses `#publish_now`):
|
145
|
-
- takes in the `original_attributes`, `object_class`, `event`, `routing_key`, `headers`
|
146
|
-
- constantizes `object_class`
|
147
|
-
- constructs routing_key using `routing_key_callable` (ignores `#attributes_for_routing_key`) or uses `routing_key` if given
|
148
|
-
- constructs headers using `headers_callable` (ignores `#attributes_for_headers`) or uses `headers` if given
|
149
|
-
- publishes Rabbit message (uses `original_attributes` as is)
|
150
|
-
- sends notification (if set up)
|
151
|
-
|
152
|
-
### Example
|
153
|
-
|
154
|
-
```ruby
|
155
|
-
TableSync::Publishing::Raw.new(
|
156
|
-
object_class: "User",
|
157
|
-
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }],
|
158
|
-
event: :create,
|
159
|
-
routing_key: :custom_key, # optional
|
160
|
-
headers: { type: "admin" }, # optional
|
161
|
-
).publish_now
|
162
|
-
```
|
data/docs/publishing.md
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
# Publishing
|
2
|
-
|
3
|
-
TableSync can be used to send data using RabbitMQ.
|
4
|
-
|
5
|
-
You can do in two ways. Automatic and manual.
|
6
|
-
Each one has its own pros and cons.
|
7
|
-
|
8
|
-
Automatic is used to publish changes in realtime, as soon as the tracked entity changes.
|
9
|
-
Usually syncs one entity at a time.
|
10
|
-
|
11
|
-
Manual allows to sync a lot of entities per message.
|
12
|
-
But demands greater amount of work and data preparation.
|
13
|
-
|
14
|
-
## Automatic
|
15
|
-
|
16
|
-
Include `TableSync.sync(self)` into a Sequel or ActiveRecord model.
|
17
|
-
|
18
|
-
Options:
|
19
|
-
|
20
|
-
- `if:` and `unless:` - Runs given proc in the scope of an instance. Skips sync on `false` for `if:` and on `true` for `unless:`.
|
21
|
-
- `on:` - specify events (`create`, `update`, `destroy`) to trigger sync on. Triggered for all of them without this option.
|
22
|
-
- `debounce_time` - min time period allowed between synchronizations.
|
23
|
-
|
24
|
-
Functioning `Rails.cache` is required.
|
25
|
-
|
26
|
-
How it works:
|
27
|
-
|
28
|
-
- `TableSync.sync(self)` - registers new callbacks (for `create`, `update`, `destroy`) for ActiveRecord model, and defines `after_create`, `after_update` and `after_destroy` callback methods for Sequel model.
|
29
|
-
|
30
|
-
- Callbacks call `TableSync::Publishing::Single#publish_later` with given options and object attributes. It enqueues a job which then publishes a message.
|
31
|
-
|
32
|
-
Example:
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
class SomeModel < Sequel::Model
|
36
|
-
TableSync.sync(self, { if: -> (*) { some_code }, unless: -> (*) { some_code }, on: [:create, :update] })
|
37
|
-
end
|
38
|
-
|
39
|
-
class SomeOtherModel < Sequel::Model
|
40
|
-
TableSync.sync(self)
|
41
|
-
end
|
42
|
-
```
|
43
|
-
|
44
|
-
### Non persisted record destruction
|
45
|
-
|
46
|
-
Sometimes destroy event can happen for non persisted record. In this case we can expect the following:
|
47
|
-
|
48
|
-
For Sequel: 'Sequel::NoExistingObject' is raised. (This is default Sequel behaviour)
|
49
|
-
For Active Record: Publishing is skipped.
|
50
|
-
|
51
|
-
Example:
|
52
|
-
|
53
|
-
```ruby
|
54
|
-
# ActiveRecord
|
55
|
-
user = User.new.destroy! # Publishing is skipped.
|
56
|
-
|
57
|
-
# Sequel
|
58
|
-
user = User.new.destroy! # raise Sequel::NoExistingObject
|
59
|
-
```
|
60
|
-
|
61
|
-
## Manual
|
62
|
-
|
63
|
-
Directly call one of the publishers. It's the best if you need to sync a lot of data.
|
64
|
-
This way you don't even need for the changes to occur.
|
65
|
-
|
66
|
-
Example:
|
67
|
-
|
68
|
-
```ruby
|
69
|
-
TableSync::Publishing::Batch.new(
|
70
|
-
object_class: "User",
|
71
|
-
original_attributes: [{ id: 1 }, { id: 2 }],
|
72
|
-
event: :update,
|
73
|
-
).publish_now
|
74
|
-
```
|
75
|
-
|
76
|
-
## Read More
|
77
|
-
|
78
|
-
- [Publishers](publishing/publishers.md)
|
79
|
-
- [Configuration](publishing/configuration.md)
|
80
|
-
- [Manual Sync (examples)](publishing/manual.md)
|
data/docs/receiving.md
DELETED
@@ -1,346 +0,0 @@
|
|
1
|
-
# Receiving changes
|
2
|
-
|
3
|
-
Naming convention for receiving handlers is `Rabbit::Handler::GROUP_ID::TableSync`,
|
4
|
-
where `GROUP_ID` represents first part of source exchange name.
|
5
|
-
Define handler class inherited from `TableSync::ReceivingHandler`
|
6
|
-
and named according to described convention.
|
7
|
-
You should use DSL inside the class.
|
8
|
-
Suppose we will synchronize models {Project, News, User} project {MainProject}, then:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
class Rabbit::Handler::MainProject::TableSync < TableSync::ReceivingHandler
|
12
|
-
queue_as :custom_queue
|
13
|
-
|
14
|
-
receive "Project", to_table: :projects
|
15
|
-
|
16
|
-
receive "News", to_table: :news, events: :update do
|
17
|
-
after_commit_on_update do
|
18
|
-
NewsCache.reload
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
receive "User", to_table: :clients, events: %i[update destroy] do
|
23
|
-
mapping_overrides email: :project_user_email, id: :project_user_id
|
24
|
-
|
25
|
-
only :project_user_email, :project_user_id, :project_id
|
26
|
-
target_keys :project_id, :project_user_id
|
27
|
-
rest_key :project_user_rest
|
28
|
-
version_key :project_user_version
|
29
|
-
|
30
|
-
additional_data do |project_id:|
|
31
|
-
{ project_id: project_id }
|
32
|
-
end
|
33
|
-
|
34
|
-
default_values do
|
35
|
-
{ created_at: Time.current }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
receive "User", to_model: CustomModel.new(:users) do
|
40
|
-
rest_key false
|
41
|
-
end
|
42
|
-
end
|
43
|
-
```
|
44
|
-
|
45
|
-
### Handler class (`Rabbit::Handler::MainProject::TableSync`)
|
46
|
-
|
47
|
-
In this case:
|
48
|
-
- `TableSync` - RabbitMQ event type.
|
49
|
-
- `MainProject` - event source.
|
50
|
-
- `Rabbit::Handler` - module for our handlers of events from RabbitMQ (there might be others)
|
51
|
-
|
52
|
-
Method `queue_as` allows you to set custom queue.
|
53
|
-
|
54
|
-
### Recieving handler batch processing
|
55
|
-
|
56
|
-
Receiving handler supports array of attributes in a single update or destroy event. Corresponding
|
57
|
-
upsert-style logic in ActiveRecord and Sequel orm handlers are provided.
|
58
|
-
|
59
|
-
### Config
|
60
|
-
```ruby
|
61
|
-
receive source, [to_table:, to_model:, events:, &block]
|
62
|
-
```
|
63
|
-
|
64
|
-
The method receives following arguments
|
65
|
-
- `source` - string, name of source model (required)
|
66
|
-
- `to_table` - destination table name (required if not set to_model)
|
67
|
-
- `to_model` - destination model (required if not set to_table)
|
68
|
-
- `events` - array of supported events (optional)
|
69
|
-
- `block` - configuration block with options (optional)
|
70
|
-
|
71
|
-
This method implements logic of mapping `source` to `to_table` (or to `to_model`) and allows customizing
|
72
|
-
the event handling logic with provided block.
|
73
|
-
You can use one `source` for a lot of `to_table` or `to_moel`.
|
74
|
-
|
75
|
-
### Options:
|
76
|
-
|
77
|
-
Most of the options can be set as computed value or as a process.
|
78
|
-
|
79
|
-
```ruby
|
80
|
-
option(value)
|
81
|
-
```
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
option do |key params|
|
85
|
-
value
|
86
|
-
end
|
87
|
-
```
|
88
|
-
|
89
|
-
Each of options can receive static value or code block which will be called for each event with the following arguments:
|
90
|
-
- `event` - type of event (`:update` or `:destroy`)
|
91
|
-
- `model` - source model (`Project`, `News`, `User` in example)
|
92
|
-
- `version` - version of the data
|
93
|
-
- `project_id` - id of project which is used in RabbitMQ
|
94
|
-
- `raw_data` - raw data from event (before applying `mapping_overrides`, `only`, etc.)
|
95
|
-
|
96
|
-
Blocks can receive any number of parameters from the list.
|
97
|
-
|
98
|
-
All specific key params will be explained in examples for each option.
|
99
|
-
|
100
|
-
#### only
|
101
|
-
Whitelist for receiving attributes.
|
102
|
-
|
103
|
-
```ruby
|
104
|
-
only(instance of Array)
|
105
|
-
```
|
106
|
-
|
107
|
-
```ruby
|
108
|
-
only do |row:|
|
109
|
-
return instance of Array
|
110
|
-
end
|
111
|
-
```
|
112
|
-
|
113
|
-
default value is taken through the call `model.columns`
|
114
|
-
|
115
|
-
#### target_keys
|
116
|
-
Primary keys or unique keys.
|
117
|
-
|
118
|
-
```ruby
|
119
|
-
target_keys(instance of Array)
|
120
|
-
```
|
121
|
-
|
122
|
-
```ruby
|
123
|
-
target_keys do |data:|
|
124
|
-
return instance of Array
|
125
|
-
end
|
126
|
-
```
|
127
|
-
|
128
|
-
default value is taken through the call `model.primary_keys`
|
129
|
-
|
130
|
-
#### rest_key
|
131
|
-
Name of jsonb column for attributes which are not included in the whitelist.
|
132
|
-
You can set the `rest_key(false)` if you won't need the rest data.
|
133
|
-
|
134
|
-
```ruby
|
135
|
-
rest_key(instance of Symbol)
|
136
|
-
```
|
137
|
-
|
138
|
-
```ruby
|
139
|
-
rest_key do |row:, rest:|
|
140
|
-
return instance of Symbol
|
141
|
-
end
|
142
|
-
```
|
143
|
-
default value is `:rest`
|
144
|
-
|
145
|
-
#### version_key
|
146
|
-
Name of version column.
|
147
|
-
|
148
|
-
```ruby
|
149
|
-
version_key(instance of Symbol)
|
150
|
-
```
|
151
|
-
|
152
|
-
```ruby
|
153
|
-
version_key do |data:|
|
154
|
-
return instance of Symbol
|
155
|
-
end
|
156
|
-
```
|
157
|
-
default value is `:version`
|
158
|
-
|
159
|
-
#### except
|
160
|
-
Blacklist for receiving attributes.
|
161
|
-
|
162
|
-
```ruby
|
163
|
-
except(instance of Array)
|
164
|
-
```
|
165
|
-
|
166
|
-
```ruby
|
167
|
-
except do |row:|
|
168
|
-
return instance of Array
|
169
|
-
end
|
170
|
-
```
|
171
|
-
|
172
|
-
default value is `[]`
|
173
|
-
|
174
|
-
#### mapping_overrides
|
175
|
-
Map for overriding receiving columns.
|
176
|
-
|
177
|
-
```ruby
|
178
|
-
mapping_overrides(instance of Hash)
|
179
|
-
```
|
180
|
-
|
181
|
-
```ruby
|
182
|
-
mapping_overrides do |row:|
|
183
|
-
return instance of Hash
|
184
|
-
end
|
185
|
-
```
|
186
|
-
|
187
|
-
default value is `{}`
|
188
|
-
|
189
|
-
#### additional_data
|
190
|
-
Additional data for insert or update (e.g. `project_id`).
|
191
|
-
|
192
|
-
```ruby
|
193
|
-
additional_data(instance of Hash)
|
194
|
-
```
|
195
|
-
|
196
|
-
```ruby
|
197
|
-
additional_data do |row:|
|
198
|
-
return instance of Hash
|
199
|
-
end
|
200
|
-
```
|
201
|
-
|
202
|
-
default value is `{}`
|
203
|
-
|
204
|
-
#### default_values
|
205
|
-
Values for insert if a row is not found.
|
206
|
-
|
207
|
-
```ruby
|
208
|
-
default_values(instance of Hash)
|
209
|
-
```
|
210
|
-
|
211
|
-
```ruby
|
212
|
-
default_values do |data:|
|
213
|
-
return instance of Hash
|
214
|
-
end
|
215
|
-
```
|
216
|
-
|
217
|
-
default value is `{}`
|
218
|
-
|
219
|
-
#### skip
|
220
|
-
Return truthy value to skip the row.
|
221
|
-
|
222
|
-
```ruby
|
223
|
-
skip(instance of TrueClass or FalseClass)
|
224
|
-
```
|
225
|
-
|
226
|
-
```ruby
|
227
|
-
skip do |data:|
|
228
|
-
return instance of TrueClass or FalseClass
|
229
|
-
end
|
230
|
-
```
|
231
|
-
|
232
|
-
default value is `false`
|
233
|
-
|
234
|
-
#### wrap_receiving
|
235
|
-
Proc that is used to wrap the receiving logic by custom block of code.
|
236
|
-
|
237
|
-
```ruby
|
238
|
-
wrap_receiving do |data:, target_keys:, version_key:, default_values: {}, event:, &receiving_logic|
|
239
|
-
receiving_logic.call
|
240
|
-
return makes no sense
|
241
|
-
end
|
242
|
-
```
|
243
|
-
|
244
|
-
event option is current fired event
|
245
|
-
default value is `proc { |&block| block.call }`
|
246
|
-
|
247
|
-
#### before_update
|
248
|
-
Perform code before updating data in the database.
|
249
|
-
|
250
|
-
```ruby
|
251
|
-
before_update do |data:, target_keys:, version_key:, default_values:|
|
252
|
-
return makes no sense
|
253
|
-
end
|
254
|
-
|
255
|
-
before_update do |data:, target_keys:, version_key:, default_values:|
|
256
|
-
return makes no sense
|
257
|
-
end
|
258
|
-
```
|
259
|
-
|
260
|
-
Сan be defined several times. Execution order guaranteed.
|
261
|
-
|
262
|
-
#### after_commit_on_update
|
263
|
-
Perform code after updated data was committed.
|
264
|
-
|
265
|
-
```ruby
|
266
|
-
after_commit_on_update do |data:, target_keys:, version_key:, default_values:, results:|
|
267
|
-
return makes no sense
|
268
|
-
end
|
269
|
-
|
270
|
-
after_commit_on_update do |data:, target_keys:, version_key:, default_values:, results:|
|
271
|
-
return makes no sense
|
272
|
-
end
|
273
|
-
```
|
274
|
-
|
275
|
-
- `results` - returned value from `model.upsert`
|
276
|
-
|
277
|
-
Сan be defined several times. Execution order guaranteed.
|
278
|
-
|
279
|
-
#### before_destroy
|
280
|
-
Perform code before destroying data in database.
|
281
|
-
|
282
|
-
```ruby
|
283
|
-
before_destroy do |data:, target_keys:, version_key:|
|
284
|
-
return makes no sense
|
285
|
-
end
|
286
|
-
|
287
|
-
before_destroy do |data:, target_keys:, version_key:|
|
288
|
-
return makes no sense
|
289
|
-
end
|
290
|
-
```
|
291
|
-
|
292
|
-
Сan be defined several times. Execution order guaranteed.
|
293
|
-
|
294
|
-
#### after_commit_on_destroy
|
295
|
-
Perform code after destroyed data was committed.
|
296
|
-
|
297
|
-
```ruby
|
298
|
-
after_commit_on_destroy do |data:, target_keys:, version_key:, results:|
|
299
|
-
return makes no sense
|
300
|
-
end
|
301
|
-
|
302
|
-
after_commit_on_destroy do |data:, target_keys:, version_key:, results:|
|
303
|
-
return makes no sense
|
304
|
-
end
|
305
|
-
```
|
306
|
-
|
307
|
-
- `results` - returned value from `model.destroy`
|
308
|
-
|
309
|
-
Сan be defined several times. Execution order guaranteed.
|
310
|
-
|
311
|
-
### Custom model
|
312
|
-
You can use custom model for receiving.
|
313
|
-
```
|
314
|
-
class Rabbit::Handler::MainProject::TableSync < TableSync::ReceivingHandler
|
315
|
-
receive "Project", to_model: CustomModel.new
|
316
|
-
end
|
317
|
-
```
|
318
|
-
|
319
|
-
This model has to implement next interface:
|
320
|
-
```
|
321
|
-
def columns
|
322
|
-
return all columns from table
|
323
|
-
end
|
324
|
-
|
325
|
-
def primary_keys
|
326
|
-
return primary keys from table
|
327
|
-
end
|
328
|
-
|
329
|
-
def upsert(data: Array, target_keys: Array, version_key: Symbol, default_values: Hash)
|
330
|
-
return array with updated rows
|
331
|
-
end
|
332
|
-
|
333
|
-
def destroy(data: Array, target_keys: Array, version_key: Symbol)
|
334
|
-
return array with delited rows
|
335
|
-
end
|
336
|
-
|
337
|
-
def transaction(&block)
|
338
|
-
block.call
|
339
|
-
return makes no sense
|
340
|
-
end
|
341
|
-
|
342
|
-
def after_commit(&block)
|
343
|
-
block.call
|
344
|
-
return makes no sense
|
345
|
-
end
|
346
|
-
```
|