cell 0.1.2 → 0.2.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 +5 -5
- data/README.md +1 -1
- data/cell.gemspec +5 -5
- data/lib/cell/clone_schema.rb +195 -192
- data/lib/cell/console.rb +11 -4
- data/lib/cell/context.rb +7 -7
- data/lib/cell/ext/active_job.rb +33 -0
- data/lib/cell/ext/active_record.rb +81 -0
- data/lib/cell/ext/migration.rb +198 -0
- data/lib/cell/meta.rb +3 -2
- data/lib/cell/railtie.rb +6 -7
- data/lib/cell/sanity_check.rb +9 -10
- data/lib/cell/schema.rb +8 -13
- data/lib/cell/tenant.rb +13 -12
- data/lib/cell/version.rb +1 -1
- metadata +16 -22
- data/lib/cell/active_job.rb +0 -32
- data/lib/cell/migration.rb +0 -201
- data/lib/cell/model_extensions.rb +0 -85
@@ -0,0 +1,198 @@
|
|
1
|
+
#
|
2
|
+
# This is the messiest part of Cell, I think by necessity.
|
3
|
+
#
|
4
|
+
# A migration has two execution modes, global and targeted, with correspond to "db:migrate" and
|
5
|
+
# "cell:db:migrate"
|
6
|
+
#
|
7
|
+
# "global" is ran with a "db:migrate", which means no Tenant is activated. DDL commands here are
|
8
|
+
# directed to either 'public' or 'cell_prototype'
|
9
|
+
#
|
10
|
+
# "targeted" is ran with a tenant activated (cell:db:migrate), and all DDL commands are directed to
|
11
|
+
# the current tenant's schema.
|
12
|
+
#
|
13
|
+
# In 'rails db:migrate' (global mode), we actually execute each migration twice: once with a
|
14
|
+
# pass_context set to :global, where ONLY commands in a 'global {}' block are executed, and then
|
15
|
+
# with pass_context set to :prototype, where ONLY commands outside of a 'global {}' block are
|
16
|
+
# executed.
|
17
|
+
#
|
18
|
+
# ContextTracker keeps up with this.
|
19
|
+
|
20
|
+
require 'cell/meta'
|
21
|
+
require 'cell/schema'
|
22
|
+
require 'cell/clone_schema'
|
23
|
+
|
24
|
+
|
25
|
+
module Cell
|
26
|
+
module Ext
|
27
|
+
module Migration
|
28
|
+
# OK, ContextTracker keeps up with:
|
29
|
+
# * The context in which this migration is being ran, e.g. the :global first pass, the
|
30
|
+
# :prototype second pass, OR the :targeted per tenant pass.
|
31
|
+
# * If it's in a global block or not, which determines if actions are actually executed
|
32
|
+
# * If force_execution is set, which is for the benefit of playing back CommandRecorder
|
33
|
+
# commands.
|
34
|
+
module ContextTracker
|
35
|
+
mattr_accessor :pass_context
|
36
|
+
mattr_accessor :global_block
|
37
|
+
mattr_accessor :force_execution
|
38
|
+
|
39
|
+
def execute_ddl?
|
40
|
+
force_execution ||
|
41
|
+
(pass_context == :global && global_block) ||
|
42
|
+
(pass_context == :prototype && !global_block) ||
|
43
|
+
(pass_context == :target && !global_block)
|
44
|
+
end
|
45
|
+
|
46
|
+
# When the CommandRecorder's commands are executed, they're rewritten to go through
|
47
|
+
# force_call, because the "effective set of commands" have already been determined by the
|
48
|
+
# CommandRecorder run.
|
49
|
+
def force_call(*args, &block)
|
50
|
+
saved, self.force_execution = self.force_execution, true
|
51
|
+
send(*args, &block)
|
52
|
+
ensure
|
53
|
+
self.force_execution = saved
|
54
|
+
end
|
55
|
+
|
56
|
+
def with_context(context, search_path, exclusive: false)
|
57
|
+
Meta::with_schema(search_path, exclusive: exclusive) do
|
58
|
+
begin
|
59
|
+
saved, self.pass_context = self.pass_context, context
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
self.pass_context = saved
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def global
|
68
|
+
saved, self.global_block = self.global_block, true
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
self.global_block = saved
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# This module intercepts create_table and drop_table, and updates the list of global tables
|
77
|
+
# in ::ActiveRecord::InternalMetadata['cell.global'].
|
78
|
+
module MetadataIntercept
|
79
|
+
def create_table(name, *args, &block)
|
80
|
+
super.tap do
|
81
|
+
Meta.add_global_table(name) if pass_context == :global
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def drop_table(name, *args, &block)
|
86
|
+
super.tap do
|
87
|
+
Meta.remove_global_table(name) if pass_context == :global
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# We intercept these methods, and only execute if appropriate according to execute_ddl?
|
93
|
+
def self.intercept(methods)
|
94
|
+
methods.each do |method|
|
95
|
+
define_method(method) do |*args, &block|
|
96
|
+
super(*args, &block) if execute_ddl?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# This sucks. In the future, we may want to pull these from SchemaStatements
|
102
|
+
intercept %i(add_belongs_to add_column add_foreign_key add_index
|
103
|
+
add_index_sort_order add_reference add_timestamps
|
104
|
+
change_column change_column_default change_column_null
|
105
|
+
change_table change_table_comment create_join_table
|
106
|
+
create_table drop_join_table drop_table
|
107
|
+
initialize_schema_migrations_table remove_belongs_to
|
108
|
+
remove_column remove_columns remove_foreign_key remove_index
|
109
|
+
remove_reference remove_timestamps rename_column
|
110
|
+
rename_column_indexes rename_index rename_table
|
111
|
+
rename_table_indexes table_alias_for table_comment) +
|
112
|
+
%i(enable_extension disable_extension truncate) +
|
113
|
+
%i(execute)
|
114
|
+
|
115
|
+
def global_schema
|
116
|
+
Meta.global_schema
|
117
|
+
end
|
118
|
+
|
119
|
+
def prototype_schema
|
120
|
+
Meta.prototype_schema
|
121
|
+
end
|
122
|
+
|
123
|
+
def tenant_schema
|
124
|
+
target.schema_name
|
125
|
+
end
|
126
|
+
|
127
|
+
def target
|
128
|
+
Model.current
|
129
|
+
end
|
130
|
+
|
131
|
+
def targeted?
|
132
|
+
!! target
|
133
|
+
end
|
134
|
+
|
135
|
+
# This is our super-special initialization function.
|
136
|
+
def initialize_cell!
|
137
|
+
CloneSchema.install_function!
|
138
|
+
execute "CREATE SCHEMA #{connection.quote_schema_name(prototype_schema)}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def exec_migration(con, direction)
|
142
|
+
if ! targeted?
|
143
|
+
with_context(:global, global_schema) do
|
144
|
+
super
|
145
|
+
end
|
146
|
+
|
147
|
+
with_context(:prototype, prototype_schema) do
|
148
|
+
super
|
149
|
+
end
|
150
|
+
else
|
151
|
+
with_context(:target, tenant_schema, exclusive: true) do
|
152
|
+
super
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Patches to CommandRecorder, which let us roll back.
|
158
|
+
module CommandRecorderFilter
|
159
|
+
# This maybe should've been attr_reader in CommandRecorder
|
160
|
+
def commands=(*)
|
161
|
+
# If this is actually used, we're fucked.
|
162
|
+
fail "The problem with monkey patching is..."
|
163
|
+
end
|
164
|
+
|
165
|
+
def commands
|
166
|
+
@commands.select do |command|
|
167
|
+
command[0]
|
168
|
+
end.map do |command|
|
169
|
+
[:force_call, [command[1], *command[2]], command[3]]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# saves the state of a recorded command with the context it was in.
|
174
|
+
def add_command(command)
|
175
|
+
@commands << [execute_ddl?, *command]
|
176
|
+
end
|
177
|
+
|
178
|
+
# We override #record to proxy through add_command
|
179
|
+
def record(*command, &block)
|
180
|
+
if @reverting
|
181
|
+
add_command inverse_of(*command, &block)
|
182
|
+
else
|
183
|
+
add_command (command << block)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
ActiveSupport.on_load(:active_record) do
|
192
|
+
ActiveRecord::Migration.prepend(Cell::Ext::Migration::ContextTracker)
|
193
|
+
ActiveRecord::Migration.prepend(Cell::Ext::Migration::MetadataIntercept)
|
194
|
+
ActiveRecord::Migration.prepend(Cell::Ext::Migration)
|
195
|
+
|
196
|
+
ActiveRecord::Migration::CommandRecorder.prepend(Cell::Ext::Migration::ContextTracker)
|
197
|
+
ActiveRecord::Migration::CommandRecorder.prepend(Cell::Ext::Migration::CommandRecorderFilter)
|
198
|
+
end
|
data/lib/cell/meta.rb
CHANGED
@@ -32,7 +32,8 @@ module Cell
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.global_schema
|
35
|
-
|
35
|
+
# This could be racy?
|
36
|
+
@global_schema ||= ::ActiveRecord::Base.connection.schema_search_path
|
36
37
|
end
|
37
38
|
|
38
39
|
def self.prototype_schema
|
@@ -40,7 +41,7 @@ module Cell
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def self.structural_schema
|
43
|
-
"#{prototype_schema}
|
44
|
+
"#{prototype_schema},#{global_schema}"
|
44
45
|
end
|
45
46
|
|
46
47
|
def self.with_global_schema(&block)
|
data/lib/cell/railtie.rb
CHANGED
@@ -11,21 +11,20 @@ module Cell
|
|
11
11
|
config.after_initialize do
|
12
12
|
require 'cell/tenant'
|
13
13
|
require 'cell/sanity_check'
|
14
|
-
require 'cell/
|
15
|
-
require 'cell/migration'
|
16
|
-
require 'cell/active_job'
|
14
|
+
require 'cell/ext/active_record'
|
15
|
+
require 'cell/ext/migration'
|
16
|
+
require 'cell/ext/active_job'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
20
|
def self.const_missing(name)
|
22
21
|
return super unless name == :Model
|
23
22
|
|
24
23
|
Rails.application.eager_load!
|
25
24
|
unless const_defined?(:Model)
|
26
|
-
fail "Eager loaded models to find
|
27
|
-
"Make sure one of your models has `prepend Cell::Tenant`"
|
25
|
+
fail "Eager loaded models to find one that uses `include Cell::Tenant`. Didn't pan out."
|
28
26
|
end
|
29
|
-
|
27
|
+
|
28
|
+
Model
|
30
29
|
end
|
31
30
|
end
|
data/lib/cell/sanity_check.rb
CHANGED
@@ -3,7 +3,7 @@ require 'active_record/connection_adapters/postgresql_adapter'
|
|
3
3
|
module Cell
|
4
4
|
module SanityCheck
|
5
5
|
def self.check_active_record_adapter!
|
6
|
-
pg_base_adapter =
|
6
|
+
pg_base_adapter = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
7
7
|
whitelist = []
|
8
8
|
adapter_name = ActiveRecord::Base.connection.adapter_name
|
9
9
|
|
@@ -18,6 +18,8 @@ module Cell
|
|
18
18
|
EOD
|
19
19
|
fail msg
|
20
20
|
end
|
21
|
+
rescue ActiveRecord::NoDatabaseError
|
22
|
+
# Not our problem
|
21
23
|
end
|
22
24
|
|
23
25
|
|
@@ -43,7 +45,7 @@ module Cell
|
|
43
45
|
Rails will not dump this schema by default with `db:structure:dump` without explicitly
|
44
46
|
setting `dump_schemas`.
|
45
47
|
|
46
|
-
You can configure this
|
48
|
+
You can configure this by adding a line like the following in application.rb:
|
47
49
|
|
48
50
|
Rails.application.config.active_record.dump_schemas = "public,cell_prototype"
|
49
51
|
EOD
|
@@ -51,14 +53,11 @@ module Cell
|
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
|
-
def self.sanity_check!
|
55
|
-
ActiveSupport.on_load(:active_record) do
|
56
|
-
Cell::SanityCheck.check_active_record_adapter!
|
57
|
-
Cell::SanityCheck.check_schema_format!
|
58
|
-
Cell::SanityCheck.check_dump_schemas!
|
59
|
-
end
|
60
|
-
end
|
61
56
|
end
|
62
57
|
end
|
63
58
|
|
64
|
-
|
59
|
+
ActiveSupport.on_load(:active_record) do
|
60
|
+
Cell::SanityCheck.check_active_record_adapter!
|
61
|
+
Cell::SanityCheck.check_schema_format!
|
62
|
+
Cell::SanityCheck.check_dump_schemas!
|
63
|
+
end
|
data/lib/cell/schema.rb
CHANGED
@@ -8,29 +8,26 @@ module Cell
|
|
8
8
|
MAX_SCHEMA_NAME_LENGTH = 63 # PostgreSQL baked-in default
|
9
9
|
MAX_CELL_ID_SIZE = MAX_SCHEMA_NAME_LENGTH - SCHEMA_PREFIX.size
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
SCHEMA_PREFIX + cell_id.to_s.gsub(/[^a-z0-9_]/i, '-')
|
14
|
-
end
|
11
|
+
def self.schema_name_for_cell_id(cell_id)
|
12
|
+
SCHEMA_PREFIX + cell_id.to_s.gsub(/[^a-z0-9_]/i, '-')
|
15
13
|
end
|
16
14
|
|
17
15
|
def schema_name
|
18
|
-
|
16
|
+
Schema.schema_name_for_cell_id(cell_id)
|
19
17
|
end
|
20
18
|
|
21
19
|
private
|
22
20
|
def create_schema!
|
23
21
|
con = self.class.connection
|
24
22
|
con.transaction do
|
25
|
-
|
26
|
-
|
23
|
+
CloneSchema.clone_schema(Meta.prototype_schema, schema_name)
|
24
|
+
CloneSchema.copy_schema_migrations_to(schema_name)
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
30
28
|
def destroy_schema!
|
31
29
|
con = self.class.connection
|
32
|
-
con.execute
|
33
|
-
"DROP SCHEMA #{con.quote_schema_name(schema_name)} CASCADE"
|
30
|
+
con.execute "DROP SCHEMA #{con.quote_schema_name(schema_name)} CASCADE"
|
34
31
|
end
|
35
32
|
|
36
33
|
def update_schema!
|
@@ -38,13 +35,11 @@ module Cell
|
|
38
35
|
src = self.class.schema_name_for_cell_id(src)
|
39
36
|
|
40
37
|
con = self.class.connection
|
41
|
-
con.execute
|
42
|
-
|
43
|
-
"TO #{con.quote_schema_name(schema_name)}"
|
38
|
+
con.execute "ALTER SCHEMA #{con.quote_schema_name(src)} RENAME " +
|
39
|
+
"TO #{con.quote_schema_name(schema_name)}"
|
44
40
|
end
|
45
41
|
|
46
42
|
def self.prepended(cls)
|
47
|
-
cls.extend(ClassMethods)
|
48
43
|
cls.after_create_commit :create_schema!
|
49
44
|
cls.after_update_commit :update_schema!, if: :cell_id_changed?
|
50
45
|
cls.after_destroy_commit :destroy_schema!
|
data/lib/cell/tenant.rb
CHANGED
@@ -4,10 +4,6 @@ require 'cell/url_options'
|
|
4
4
|
|
5
5
|
module Cell
|
6
6
|
module Tenant
|
7
|
-
class << self
|
8
|
-
attr_accessor :cls
|
9
|
-
end
|
10
|
-
|
11
7
|
module ClassMethods
|
12
8
|
def cell_id_column
|
13
9
|
:id
|
@@ -35,21 +31,26 @@ module Cell
|
|
35
31
|
previous_changes[self.class.cell_id_column]
|
36
32
|
end
|
37
33
|
|
38
|
-
def self.
|
39
|
-
|
34
|
+
def self.append_features(cls)
|
35
|
+
cls.prepend(self)
|
40
36
|
end
|
41
37
|
|
42
|
-
def self.
|
43
|
-
|
38
|
+
def self.extend_object(cls)
|
39
|
+
cls.prepend(self)
|
40
|
+
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
::Cell.const_set(:Model, model)
|
42
|
+
def self.prepended(model)
|
43
|
+
Cell.assign_model(model)
|
49
44
|
|
45
|
+
model.extend(ClassMethods)
|
50
46
|
model.prepend(::Cell::Schema)
|
51
47
|
model.prepend(::Cell::Context)
|
52
48
|
model.prepend(::Cell::UrlOptions)
|
53
49
|
end
|
54
50
|
end
|
51
|
+
|
52
|
+
def self.assign_model(model)
|
53
|
+
remove_const(:Model) if const_defined?(:Model)
|
54
|
+
const_set(:Model, model)
|
55
|
+
end
|
55
56
|
end
|
data/lib/cell/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Owens
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,76 +16,70 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 5.0.0.1
|
19
|
+
version: 5.2.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 5.
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 5.0.0.1
|
26
|
+
version: 5.2.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: pg
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
36
30
|
requirements:
|
37
31
|
- - "~>"
|
38
32
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
33
|
+
version: 1.1.3
|
40
34
|
type: :runtime
|
41
35
|
prerelease: false
|
42
36
|
version_requirements: !ruby/object:Gem::Requirement
|
43
37
|
requirements:
|
44
38
|
- - "~>"
|
45
39
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
40
|
+
version: 1.1.3
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
42
|
name: minitest
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
50
44
|
requirements:
|
51
45
|
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version: 5.
|
47
|
+
version: '5.11'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
51
|
requirements:
|
58
52
|
- - "~>"
|
59
53
|
- !ruby/object:Gem::Version
|
60
|
-
version: 5.
|
54
|
+
version: '5.11'
|
61
55
|
- !ruby/object:Gem::Dependency
|
62
56
|
name: bundler
|
63
57
|
requirement: !ruby/object:Gem::Requirement
|
64
58
|
requirements:
|
65
59
|
- - "~>"
|
66
60
|
- !ruby/object:Gem::Version
|
67
|
-
version: '1.
|
61
|
+
version: '1.16'
|
68
62
|
type: :development
|
69
63
|
prerelease: false
|
70
64
|
version_requirements: !ruby/object:Gem::Requirement
|
71
65
|
requirements:
|
72
66
|
- - "~>"
|
73
67
|
- !ruby/object:Gem::Version
|
74
|
-
version: '1.
|
68
|
+
version: '1.16'
|
75
69
|
- !ruby/object:Gem::Dependency
|
76
70
|
name: rake
|
77
71
|
requirement: !ruby/object:Gem::Requirement
|
78
72
|
requirements:
|
79
73
|
- - "~>"
|
80
74
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
75
|
+
version: '12.3'
|
82
76
|
type: :development
|
83
77
|
prerelease: false
|
84
78
|
version_requirements: !ruby/object:Gem::Requirement
|
85
79
|
requirements:
|
86
80
|
- - "~>"
|
87
81
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
82
|
+
version: '12.3'
|
89
83
|
description:
|
90
84
|
email:
|
91
85
|
- mike@meter.md
|
@@ -103,13 +97,13 @@ files:
|
|
103
97
|
- bin/test
|
104
98
|
- cell.gemspec
|
105
99
|
- lib/cell.rb
|
106
|
-
- lib/cell/active_job.rb
|
107
100
|
- lib/cell/clone_schema.rb
|
108
101
|
- lib/cell/console.rb
|
109
102
|
- lib/cell/context.rb
|
103
|
+
- lib/cell/ext/active_job.rb
|
104
|
+
- lib/cell/ext/active_record.rb
|
105
|
+
- lib/cell/ext/migration.rb
|
110
106
|
- lib/cell/meta.rb
|
111
|
-
- lib/cell/migration.rb
|
112
|
-
- lib/cell/model_extensions.rb
|
113
107
|
- lib/cell/railtie.rb
|
114
108
|
- lib/cell/sanity_check.rb
|
115
109
|
- lib/cell/schema.rb
|
@@ -138,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
132
|
version: '0'
|
139
133
|
requirements: []
|
140
134
|
rubyforge_project:
|
141
|
-
rubygems_version: 2.
|
135
|
+
rubygems_version: 2.7.8
|
142
136
|
signing_key:
|
143
137
|
specification_version: 4
|
144
138
|
summary: Provides isolation and tenancy for Rails
|
data/lib/cell/active_job.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Cell
|
2
|
-
module ActiveJob
|
3
|
-
KEY = :'Cell.tenant'
|
4
|
-
|
5
|
-
def serialize
|
6
|
-
if (current_id = ::Cell::Model.current&.cell_id)
|
7
|
-
super.merge(KEY => current_id)
|
8
|
-
else
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def deserialize(job_data)
|
14
|
-
if job_data.key?(KEY)
|
15
|
-
self.cell_tenant = ::Cell::Model.cell_find(job_data[KEY])
|
16
|
-
end
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.prepended(cls)
|
21
|
-
cls.send(:attr_accessor, :cell_tenant)
|
22
|
-
cls.around_perform do |job, block|
|
23
|
-
::Cell::Model.use(job.cell_tenant, &block)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
if defined?(::ActiveJob)
|
31
|
-
::ActiveJob::Base.prepend(::Cell::ActiveJob)
|
32
|
-
end
|