adaptive_alias 0.0.2 → 0.0.3
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/ruby.yml +70 -70
- data/.gitignore +62 -62
- data/.rubocop.yml +1227 -1227
- data/CHANGELOG.md +2 -1
- data/CODE_OF_CONDUCT.md +49 -49
- data/LICENSE +21 -21
- data/README.md +67 -67
- data/Rakefile +10 -10
- data/adaptive_alias.gemspec +44 -44
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/gemfiles/6.0.gemfile +11 -10
- data/gemfiles/6.1.gemfile +11 -10
- data/gemfiles/7.0.gemfile +12 -11
- data/lib/adaptive_alias/active_model_patches/read_attribute.rb +20 -20
- data/lib/adaptive_alias/active_model_patches/remove_alias_attribute.rb +27 -27
- data/lib/adaptive_alias/hooks/association.rb +13 -13
- data/lib/adaptive_alias/hooks/association_scope.rb +13 -13
- data/lib/adaptive_alias/hooks/relation.rb +21 -21
- data/lib/adaptive_alias/hooks/singular_association.rb +13 -13
- data/lib/adaptive_alias/patches/backward_patch.rb +21 -21
- data/lib/adaptive_alias/patches/base.rb +75 -75
- data/lib/adaptive_alias/patches/forward_patch.rb +21 -21
- data/lib/adaptive_alias/version.rb +3 -3
- data/lib/adaptive_alias.rb +73 -65
- metadata +6 -6
@@ -1,13 +1,13 @@
|
|
1
|
-
module AdaptiveAlias
|
2
|
-
module Hooks
|
3
|
-
module AssociationScope
|
4
|
-
def last_chain_scope(*)
|
5
|
-
AdaptiveAlias.rescue_missing_attribute{ super }
|
6
|
-
end
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class ActiveRecord::Associations::AssociationScope
|
12
|
-
prepend AdaptiveAlias::Hooks::AssociationScope
|
13
|
-
end
|
1
|
+
module AdaptiveAlias
|
2
|
+
module Hooks
|
3
|
+
module AssociationScope
|
4
|
+
def last_chain_scope(*)
|
5
|
+
AdaptiveAlias.rescue_missing_attribute{ super }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ActiveRecord::Associations::AssociationScope
|
12
|
+
prepend AdaptiveAlias::Hooks::AssociationScope
|
13
|
+
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
module AdaptiveAlias
|
2
|
-
module Hooks
|
3
|
-
module Relation
|
4
|
-
def pluck(*)
|
5
|
-
AdaptiveAlias.rescue_statement_invalid(self){ super }
|
6
|
-
end
|
7
|
-
|
8
|
-
def select_all(*)
|
9
|
-
AdaptiveAlias.rescue_statement_invalid(self){ super }
|
10
|
-
end
|
11
|
-
|
12
|
-
def exec_queries(*)
|
13
|
-
AdaptiveAlias.rescue_statement_invalid(self){ super }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class ActiveRecord::Relation
|
20
|
-
prepend AdaptiveAlias::Hooks::Relation
|
21
|
-
end
|
1
|
+
module AdaptiveAlias
|
2
|
+
module Hooks
|
3
|
+
module Relation
|
4
|
+
def pluck(*)
|
5
|
+
AdaptiveAlias.rescue_statement_invalid(self){ super }
|
6
|
+
end
|
7
|
+
|
8
|
+
def select_all(*)
|
9
|
+
AdaptiveAlias.rescue_statement_invalid(self){ super }
|
10
|
+
end
|
11
|
+
|
12
|
+
def exec_queries(*)
|
13
|
+
AdaptiveAlias.rescue_statement_invalid(self){ super }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ActiveRecord::Relation
|
20
|
+
prepend AdaptiveAlias::Hooks::Relation
|
21
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
module AdaptiveAlias
|
2
|
-
module Hooks
|
3
|
-
module SingularAssociation
|
4
|
-
def reader(*)
|
5
|
-
AdaptiveAlias.rescue_missing_attribute{ super }
|
6
|
-
end
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class ActiveRecord::Associations::SingularAssociation
|
12
|
-
prepend AdaptiveAlias::Hooks::SingularAssociation
|
13
|
-
end
|
1
|
+
module AdaptiveAlias
|
2
|
+
module Hooks
|
3
|
+
module SingularAssociation
|
4
|
+
def reader(*)
|
5
|
+
AdaptiveAlias.rescue_missing_attribute{ super }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ActiveRecord::Associations::SingularAssociation
|
12
|
+
prepend AdaptiveAlias::Hooks::SingularAssociation
|
13
|
+
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'adaptive_alias/patches/base'
|
4
|
-
|
5
|
-
module AdaptiveAlias
|
6
|
-
module Patches
|
7
|
-
class BackwardPatch < Base
|
8
|
-
def apply!
|
9
|
-
AdaptiveAlias.current_patches[[@klass, @old_column, @new_column]] = self
|
10
|
-
@klass.alias_attribute(@old_column, @new_column)
|
11
|
-
add_hooks!(current_column: @new_column, alias_column: @old_column, log_warning: true)
|
12
|
-
end
|
13
|
-
|
14
|
-
def remove!
|
15
|
-
super
|
16
|
-
@klass.remove_alias_attribute(@old_column)
|
17
|
-
ForwardPatch.new(@klass, @old_column, @new_column).apply!
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adaptive_alias/patches/base'
|
4
|
+
|
5
|
+
module AdaptiveAlias
|
6
|
+
module Patches
|
7
|
+
class BackwardPatch < Base
|
8
|
+
def apply!
|
9
|
+
AdaptiveAlias.current_patches[[@klass, @old_column, @new_column]] = self
|
10
|
+
@klass.alias_attribute(@old_column, @new_column)
|
11
|
+
add_hooks!(current_column: @new_column, alias_column: @old_column, log_warning: true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove!
|
15
|
+
super
|
16
|
+
@klass.remove_alias_attribute(@old_column)
|
17
|
+
ForwardPatch.new(@klass, @old_column, @new_column).apply!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,75 +1,75 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AdaptiveAlias
|
4
|
-
module Patches
|
5
|
-
class Base
|
6
|
-
attr_reader :fix_association
|
7
|
-
attr_reader :fix_missing_attribute
|
8
|
-
attr_reader :removed
|
9
|
-
|
10
|
-
def initialize(klass, old_column, new_column)
|
11
|
-
@klass = klass
|
12
|
-
@old_column = old_column
|
13
|
-
@new_column = new_column
|
14
|
-
end
|
15
|
-
|
16
|
-
def add_hooks!(current_column:, alias_column:, log_warning: false)
|
17
|
-
patch = self
|
18
|
-
old_column = @old_column
|
19
|
-
new_column = @new_column
|
20
|
-
|
21
|
-
AdaptiveAlias.get_or_create_model_module(@klass).instance_exec do
|
22
|
-
remove_method(new_column) if method_defined?(new_column)
|
23
|
-
define_method(new_column) do
|
24
|
-
AdaptiveAlias.rescue_missing_attribute{ self[new_column] }
|
25
|
-
end
|
26
|
-
|
27
|
-
remove_method(old_column) if method_defined?(old_column)
|
28
|
-
define_method(old_column) do
|
29
|
-
patch.log_warning if log_warning
|
30
|
-
AdaptiveAlias.rescue_missing_attribute{ self[old_column] }
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
expected_error_message = "Mysql2::Error: Unknown column '#{@klass.table_name}.#{current_column}' in 'where clause'".freeze
|
35
|
-
|
36
|
-
@fix_missing_attribute = proc do
|
37
|
-
next false if patch.removed
|
38
|
-
|
39
|
-
patch.remove!
|
40
|
-
next true
|
41
|
-
end
|
42
|
-
|
43
|
-
@fix_association = proc do |target, error|
|
44
|
-
next false if patch.removed || error.message != expected_error_message
|
45
|
-
|
46
|
-
patch.remove!
|
47
|
-
|
48
|
-
if target
|
49
|
-
hash = target.where_values_hash
|
50
|
-
hash[alias_column] = hash.delete(current_column) if hash.key?(current_column)
|
51
|
-
target.instance_variable_set(:@arel, nil)
|
52
|
-
target.unscope!(:where).where!(hash)
|
53
|
-
end
|
54
|
-
|
55
|
-
next true
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def log_warning
|
60
|
-
if @prev_warning_time == nil || @prev_warning_time < AdaptiveAlias.log_interval.ago
|
61
|
-
@prev_warning_time = Time.now
|
62
|
-
AdaptiveAlias.unexpected_old_column_proc&.call
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def remove!
|
67
|
-
@removed = true
|
68
|
-
@klass.send(:reload_schema_from_cache)
|
69
|
-
@klass.initialize_find_by_cache
|
70
|
-
@fix_association = nil
|
71
|
-
@fix_missing_attribute = nil
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AdaptiveAlias
|
4
|
+
module Patches
|
5
|
+
class Base
|
6
|
+
attr_reader :fix_association
|
7
|
+
attr_reader :fix_missing_attribute
|
8
|
+
attr_reader :removed
|
9
|
+
|
10
|
+
def initialize(klass, old_column, new_column)
|
11
|
+
@klass = klass
|
12
|
+
@old_column = old_column
|
13
|
+
@new_column = new_column
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_hooks!(current_column:, alias_column:, log_warning: false)
|
17
|
+
patch = self
|
18
|
+
old_column = @old_column
|
19
|
+
new_column = @new_column
|
20
|
+
|
21
|
+
AdaptiveAlias.get_or_create_model_module(@klass).instance_exec do
|
22
|
+
remove_method(new_column) if method_defined?(new_column)
|
23
|
+
define_method(new_column) do
|
24
|
+
AdaptiveAlias.rescue_missing_attribute{ self[new_column] }
|
25
|
+
end
|
26
|
+
|
27
|
+
remove_method(old_column) if method_defined?(old_column)
|
28
|
+
define_method(old_column) do
|
29
|
+
patch.log_warning if log_warning
|
30
|
+
AdaptiveAlias.rescue_missing_attribute{ self[old_column] }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
expected_error_message = "Mysql2::Error: Unknown column '#{@klass.table_name}.#{current_column}' in 'where clause'".freeze
|
35
|
+
|
36
|
+
@fix_missing_attribute = proc do
|
37
|
+
next false if patch.removed
|
38
|
+
|
39
|
+
patch.remove!
|
40
|
+
next true
|
41
|
+
end
|
42
|
+
|
43
|
+
@fix_association = proc do |target, error|
|
44
|
+
next false if patch.removed || error.message != expected_error_message
|
45
|
+
|
46
|
+
patch.remove!
|
47
|
+
|
48
|
+
if target
|
49
|
+
hash = target.where_values_hash
|
50
|
+
hash[alias_column] = hash.delete(current_column) if hash.key?(current_column)
|
51
|
+
target.instance_variable_set(:@arel, nil)
|
52
|
+
target.unscope!(:where).where!(hash)
|
53
|
+
end
|
54
|
+
|
55
|
+
next true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def log_warning
|
60
|
+
if @prev_warning_time == nil || @prev_warning_time < AdaptiveAlias.log_interval.ago
|
61
|
+
@prev_warning_time = Time.now
|
62
|
+
AdaptiveAlias.unexpected_old_column_proc&.call
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def remove!
|
67
|
+
@removed = true
|
68
|
+
@klass.send(:reload_schema_from_cache)
|
69
|
+
@klass.initialize_find_by_cache
|
70
|
+
@fix_association = nil
|
71
|
+
@fix_missing_attribute = nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'adaptive_alias/patches/base'
|
4
|
-
|
5
|
-
module AdaptiveAlias
|
6
|
-
module Patches
|
7
|
-
class ForwardPatch < Base
|
8
|
-
def apply!
|
9
|
-
AdaptiveAlias.current_patches[[@klass, @old_column, @new_column]] = self
|
10
|
-
@klass.alias_attribute(@new_column, @old_column)
|
11
|
-
add_hooks!(current_column: @old_column, alias_column: @new_column)
|
12
|
-
end
|
13
|
-
|
14
|
-
def remove!
|
15
|
-
super
|
16
|
-
@klass.remove_alias_attribute(@new_column)
|
17
|
-
BackwardPatch.new(@klass, @old_column, @new_column).apply!
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adaptive_alias/patches/base'
|
4
|
+
|
5
|
+
module AdaptiveAlias
|
6
|
+
module Patches
|
7
|
+
class ForwardPatch < Base
|
8
|
+
def apply!
|
9
|
+
AdaptiveAlias.current_patches[[@klass, @old_column, @new_column]] = self
|
10
|
+
@klass.alias_attribute(@new_column, @old_column)
|
11
|
+
add_hooks!(current_column: @old_column, alias_column: @new_column)
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove!
|
15
|
+
super
|
16
|
+
@klass.remove_alias_attribute(@new_column)
|
17
|
+
BackwardPatch.new(@klass, @old_column, @new_column).apply!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
module AdaptiveAlias
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
1
|
+
module AdaptiveAlias
|
2
|
+
VERSION = '0.0.3'
|
3
|
+
end
|
data/lib/adaptive_alias.rb
CHANGED
@@ -1,65 +1,73 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'adaptive_alias/version'
|
4
|
-
require 'adaptive_alias/active_model_patches/read_attribute'
|
5
|
-
require 'adaptive_alias/active_model_patches/remove_alias_attribute'
|
6
|
-
require 'adaptive_alias/patches/backward_patch'
|
7
|
-
require 'adaptive_alias/patches/forward_patch'
|
8
|
-
|
9
|
-
require 'adaptive_alias/hooks/association'
|
10
|
-
require 'adaptive_alias/hooks/association_scope'
|
11
|
-
require 'adaptive_alias/hooks/singular_association'
|
12
|
-
require 'adaptive_alias/hooks/relation'
|
13
|
-
|
14
|
-
module AdaptiveAlias
|
15
|
-
@log_interval = 10 * 60
|
16
|
-
@current_patches = {}
|
17
|
-
@model_modules ||= {}
|
18
|
-
|
19
|
-
class << self
|
20
|
-
attr_accessor :unexpected_old_column_proc
|
21
|
-
attr_accessor :log_interval
|
22
|
-
attr_accessor :current_patches
|
23
|
-
end
|
24
|
-
|
25
|
-
class << self
|
26
|
-
def [](old_column, new_column)
|
27
|
-
old_column = old_column.to_sym
|
28
|
-
new_column = new_column.to_sym
|
29
|
-
|
30
|
-
Module.new do
|
31
|
-
extend ActiveSupport::Concern
|
32
|
-
|
33
|
-
included do
|
34
|
-
if column_names.include?(new_column)
|
35
|
-
Patches::BackwardPatch.new(self, old_column, new_column).apply!
|
36
|
-
else
|
37
|
-
Patches::ForwardPatch.new(self, old_column, new_column).apply!
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def rescue_statement_invalid(relation)
|
44
|
-
yield
|
45
|
-
rescue ActiveRecord::StatementInvalid => error
|
46
|
-
raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_association.call(relation, error) }
|
47
|
-
retry
|
48
|
-
end
|
49
|
-
|
50
|
-
def rescue_missing_attribute
|
51
|
-
yield
|
52
|
-
rescue ActiveModel::MissingAttributeError => error
|
53
|
-
raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_missing_attribute.call }
|
54
|
-
retry
|
55
|
-
end
|
56
|
-
|
57
|
-
def get_or_create_model_module(klass)
|
58
|
-
return @model_modules[klass] if @model_modules[klass]
|
59
|
-
|
60
|
-
@model_modules[klass] = Module.new
|
61
|
-
klass.prepend(@model_modules[klass])
|
62
|
-
return @model_modules[klass]
|
63
|
-
end
|
64
|
-
|
65
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adaptive_alias/version'
|
4
|
+
require 'adaptive_alias/active_model_patches/read_attribute'
|
5
|
+
require 'adaptive_alias/active_model_patches/remove_alias_attribute'
|
6
|
+
require 'adaptive_alias/patches/backward_patch'
|
7
|
+
require 'adaptive_alias/patches/forward_patch'
|
8
|
+
|
9
|
+
require 'adaptive_alias/hooks/association'
|
10
|
+
require 'adaptive_alias/hooks/association_scope'
|
11
|
+
require 'adaptive_alias/hooks/singular_association'
|
12
|
+
require 'adaptive_alias/hooks/relation'
|
13
|
+
|
14
|
+
module AdaptiveAlias
|
15
|
+
@log_interval = 10 * 60
|
16
|
+
@current_patches = {}
|
17
|
+
@model_modules ||= {}
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_accessor :unexpected_old_column_proc
|
21
|
+
attr_accessor :log_interval
|
22
|
+
attr_accessor :current_patches
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def [](old_column, new_column)
|
27
|
+
old_column = old_column.to_sym
|
28
|
+
new_column = new_column.to_sym
|
29
|
+
|
30
|
+
Module.new do
|
31
|
+
extend ActiveSupport::Concern
|
32
|
+
|
33
|
+
included do
|
34
|
+
if column_names.include?(new_column)
|
35
|
+
Patches::BackwardPatch.new(self, old_column, new_column).apply!
|
36
|
+
else
|
37
|
+
Patches::ForwardPatch.new(self, old_column, new_column).apply!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def rescue_statement_invalid(relation)
|
44
|
+
yield
|
45
|
+
rescue ActiveRecord::StatementInvalid => error
|
46
|
+
raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_association.call(relation, error) }
|
47
|
+
retry
|
48
|
+
end
|
49
|
+
|
50
|
+
def rescue_missing_attribute
|
51
|
+
yield
|
52
|
+
rescue ActiveModel::MissingAttributeError => error
|
53
|
+
raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_missing_attribute.call }
|
54
|
+
retry
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_or_create_model_module(klass)
|
58
|
+
return @model_modules[klass] if @model_modules[klass]
|
59
|
+
|
60
|
+
@model_modules[klass] = Module.new
|
61
|
+
klass.prepend(@model_modules[klass])
|
62
|
+
return @model_modules[klass]
|
63
|
+
end
|
64
|
+
|
65
|
+
def missing_value?(attributes, klass, name)
|
66
|
+
return false if attributes.key?(name)
|
67
|
+
|
68
|
+
old_name = klass.attribute_aliases.key(name)
|
69
|
+
return false if old_name == nil
|
70
|
+
return !!AdaptiveAlias.current_patches[[klass, old_name.to_sym, name.to_sym]]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adaptive_alias
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- khiav reoy
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -142,7 +142,7 @@ metadata:
|
|
142
142
|
source_code_uri: https://github.com/khiav223577/adaptive_alias
|
143
143
|
documentation_uri: https://www.rubydoc.info/gems/adaptive_alias
|
144
144
|
bug_tracker_uri: https://github.com/khiav223577/adaptive_alias/issues
|
145
|
-
post_install_message:
|
145
|
+
post_install_message:
|
146
146
|
rdoc_options: []
|
147
147
|
require_paths:
|
148
148
|
- lib
|
@@ -157,8 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: '0'
|
159
159
|
requirements: []
|
160
|
-
rubygems_version: 3.
|
161
|
-
signing_key:
|
160
|
+
rubygems_version: 3.2.14
|
161
|
+
signing_key:
|
162
162
|
specification_version: 4
|
163
163
|
summary: Extend attribute_alias and make it be adaptive with realtime database schema
|
164
164
|
test_files: []
|