table_sync 6.0.4 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
```
|