adaptive_alias 0.0.1 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f96c867d9849406b6dc38c2d535e6ecf1e62d4de7793d79e78e474588467fc6
4
- data.tar.gz: f1b3ff5b3be19513a263212e98c80423f40955af50f744d7f4958202dfaf8659
3
+ metadata.gz: 81757ab8f4098990940d499ee2286c8c831fdac6462dfcafcd59b868ff596ec2
4
+ data.tar.gz: b88816e4745352dc63fb29a4d102a52935538bd0f5ef5591f8ce56e9057dc9d5
5
5
  SHA512:
6
- metadata.gz: 3f8f92726071ac5e064dadc6c9aeb96dc72ed3d99c98fe982988405ce1336cf7978a9720dff958e9555464f9edd791370056ce4dec6190d707f06d77c349c686
7
- data.tar.gz: 4d70ffe7088a940742a5c0cd12b0ee6f0249abe6c9cd75c162f0e277cf1066ca086ad8e28d4a6253c2cb103bc9e512e068be498d11305ea1b0563818a8100f30
6
+ metadata.gz: 60cb4e6e2f31787f93f6edf5415bd3fbe283999c50d0fba89d9e48e055a5c06ca7479ee8a158ec4618453352bc8034a18e9acbafae5905f4e4f2a7a0ee8ba54f
7
+ data.tar.gz: e80d6cdd3e41254d07e70e4440bc120b6940bfddb31f54709e97becafc18dd4eef2341832fc049d750e247e002a8097f4d9128697de0f657c8fdd1b47310d103
data/.rubocop.yml CHANGED
@@ -222,9 +222,9 @@ Metrics/CyclomaticComplexity:
222
222
  Enabled: true
223
223
 
224
224
  Layout/LineLength:
225
- Description: 'Limit lines to 120 characters.'
225
+ Description: 'Limit lines to 160 characters.'
226
226
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits'
227
- Max: 120
227
+ Max: 160
228
228
  Enabled: true
229
229
  Exclude:
230
230
  - 'config/locales/**'
data/CHANGELOG.md CHANGED
@@ -1 +1,10 @@
1
- ## Change Log
1
+ ## Change Log
2
+
3
+ ### [v0.0.3](https://github.com/khiav223577/adaptive_alias/compare/v0.0.2...v0.0.3) 2022/07/27
4
+ - [#3](https://github.com/khiav223577/adaptive_alias/pull/3) Fix: prevent calling custom column names from raising missing attributes (@khiav223577)
5
+
6
+ ### [v0.0.2](https://github.com/khiav223577/adaptive_alias/compare/v0.0.1...v0.0.2) 2022/07/26
7
+ - [#2](https://github.com/khiav223577/adaptive_alias/pull/2) Doesn't need rails_compatibility in runtime (@khiav223577)
8
+
9
+ ### v0.0.1 2022/07/22
10
+ - [#1](https://github.com/khiav223577/adaptive_alias/pull/1) Implement adaptive_alias features (@khiav223577)
data/README.md CHANGED
@@ -8,6 +8,27 @@
8
8
 
9
9
  Extend attribute_alias and make it be adaptive with realtime database schema.
10
10
 
11
+ When we are going to rename a column, we may want to add a forward-patch so that we can use new column name before migration. And after migration, we may want to add a backward-patch so that those where are still using old column name will not be broken.
12
+ Ideally, we switch from forward-patch to backward-patch right after migration:
13
+ ```rb
14
+ ForwardPatch migrate BackwardPatch
15
+ |----------------------------------------|----------------------------------------|
16
+
17
+ ```
18
+
19
+ But in reality, it will take times to deploy and restart server to switch patch. There is a gap between migration and restart. So what will happen when db is migrated but server is not restarted?
20
+ We need a way to automatically adjust the patch to adapt current schema.
21
+
22
+ ```rb
23
+ ForwardPatch migrate restart BackwardPatch
24
+ |----------------------------------------|---@-----|-------------------------------|
25
+
26
+ ```
27
+
28
+ This is what this gem wants to achieve. We don't want to do complex migrations, take care of backward-compatibiliy, and have any downtime.
29
+ Just rely on this gem.
30
+
31
+
11
32
  ## Supports
12
33
  - Ruby 2.6 ~ 2.7, 3.0 ~ 3.1
13
34
  - Rails 6.0, 6.1, 7.0
@@ -38,8 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency 'rake', '~> 12.0'
39
39
  spec.add_development_dependency 'sqlite3', '~> 1.3'
40
40
  spec.add_development_dependency 'minitest', '~> 5.0'
41
- spec.add_development_dependency 'backports', '~> 3.15.0'
41
+ spec.add_development_dependency 'rails_compatibility', '>= 0.0.8'
42
42
 
43
43
  spec.add_dependency 'activerecord', '>= 3'
44
- spec.add_dependency 'rails_compatibility', '>= 0.0.8'
45
44
  end
data/gemfiles/6.0.gemfile CHANGED
@@ -5,6 +5,7 @@ gem 'activerecord', '~> 6.0.0'
5
5
  group :test do
6
6
  gem 'simplecov', '< 0.18'
7
7
  gem 'mysql2', '0.5.3'
8
+ gem 'acts-as-taggable-on', '~> 7.0.0'
8
9
  end
9
10
 
10
11
  gemspec path: '../'
data/gemfiles/6.1.gemfile CHANGED
@@ -5,6 +5,7 @@ gem 'activerecord', '~> 6.1.3'
5
5
  group :test do
6
6
  gem 'simplecov', '< 0.18'
7
7
  gem 'mysql2', '0.5.3'
8
+ gem 'acts-as-taggable-on', '~> 7.0.0'
8
9
  end
9
10
 
10
11
  gemspec path: '../'
data/gemfiles/7.0.gemfile CHANGED
@@ -6,6 +6,7 @@ gem 'activerecord', '~> 7.0.0'
6
6
  group :test do
7
7
  gem 'simplecov', '< 0.18'
8
8
  gem 'mysql2', '0.5.3'
9
+ gem 'acts-as-taggable-on', '~> 9.0.0'
9
10
  end
10
11
 
11
12
  gemspec path: '../'
@@ -9,12 +9,14 @@ module ActiveRecord::AttributeMethods::Read
9
9
  _read_attribute(name, &block)
10
10
  end
11
11
 
12
+ # This method exists to avoid the expensive primary_key check internally, without
13
+ # breaking compatibility with the write_attribute API
12
14
  def _read_attribute(attr_name, &block) # :nodoc:
13
15
  name = attr_name.to_s
14
16
  name = self.class.attribute_aliases[name] || name
15
17
 
16
18
  sync_with_transaction_state if @transaction_state&.finalized?
17
- return yield if block_given? && !@attributes.key?(name)
18
- @attributes.fetch_value(name, &block)
19
+ return yield(name) if block_given? and AdaptiveAlias.missing_value?(@attributes, self.class, name)
20
+ return @attributes.fetch_value(name, &block)
19
21
  end
20
22
  end
@@ -3,19 +3,10 @@ require 'active_model'
3
3
  module ActiveModel::AttributeMethods
4
4
  module ClassMethods
5
5
  def remove_proxy_call(mod, name)
6
- defn = if NAME_COMPILABLE_REGEXP.match?(name)
7
- "undef #{name}"
8
- else
9
- "remove_method(:'#{name}')"
10
- end
11
-
12
- mod.module_eval defn, __FILE__, __LINE__ + 1
6
+ mod.module_eval "remove_method(:'#{name}')", __FILE__, __LINE__ + 1
13
7
  end
14
8
 
15
9
  def remove_alias_attribute(new_name)
16
- # association_scope -> add_constraints -> last_chain_scope -> where!(key => model[foreign_key])
17
- # self[attr_name] -> read_attribute(attr_name) -> attribute_aliases
18
- # where! -> where_clause_factory.build -> attributes = predicate_builder.resolve_column_aliases(opts) -> attribute_aliases
19
10
  self.attribute_aliases = attribute_aliases.except(new_name.to_s)
20
11
 
21
12
  attribute_method_matchers.each do |matcher|
@@ -0,0 +1,22 @@
1
+ require 'active_record'
2
+
3
+ module ActiveRecord::AttributeMethods::Write
4
+ def write_attribute(attr_name, value)
5
+ name = attr_name.to_s
6
+ name = self.class.attribute_aliases[name] || name
7
+
8
+ name = @primary_key if name == 'id' && @primary_key
9
+ _write_attribute(name, value)
10
+ end
11
+
12
+ # This method exists to avoid the expensive primary_key check internally, without
13
+ # breaking compatibility with the write_attribute API
14
+ def _write_attribute(attr_name, value) # :nodoc:
15
+ name = attr_name.to_s
16
+ name = self.class.attribute_aliases[name] || name
17
+
18
+ sync_with_transaction_state if @transaction_state&.finalized?
19
+ @attributes.write_from_user(name, value)
20
+ value
21
+ end
22
+ end
@@ -4,6 +4,10 @@ module AdaptiveAlias
4
4
  def find_target(*)
5
5
  AdaptiveAlias.rescue_statement_invalid(nil){ super }
6
6
  end
7
+
8
+ def create!(attributes = {}, &block)
9
+ AdaptiveAlias.rescue_statement_invalid(association_scope){ super }
10
+ end
7
11
  end
8
12
  end
9
13
  end
@@ -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(_scope, reflection, owner)
5
+ AdaptiveAlias.rescue_missing_attribute(owner.class){ super }
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ class ActiveRecord::Associations::AssociationScope
12
+ prepend AdaptiveAlias::Hooks::AssociationScope
13
+ end
@@ -2,7 +2,7 @@ module AdaptiveAlias
2
2
  module Hooks
3
3
  module SingularAssociation
4
4
  def reader(*)
5
- AdaptiveAlias.rescue_missing_attribute{ super }
5
+ AdaptiveAlias.rescue_missing_attribute(owner.class){ super }
6
6
  end
7
7
  end
8
8
  end
@@ -4,7 +4,7 @@ require 'adaptive_alias/patches/base'
4
4
 
5
5
  module AdaptiveAlias
6
6
  module Patches
7
- class BackPatch < Base
7
+ class BackwardPatch < Base
8
8
  def apply!
9
9
  AdaptiveAlias.current_patches[[@klass, @old_column, @new_column]] = self
10
10
  @klass.alias_attribute(@old_column, @new_column)
@@ -14,6 +14,7 @@ module AdaptiveAlias
14
14
  def remove!
15
15
  super
16
16
  @klass.remove_alias_attribute(@old_column)
17
+ @klass.define_attribute_method(@old_column)
17
18
  ForwardPatch.new(@klass, @old_column, @new_column).apply!
18
19
  end
19
20
  end
@@ -6,6 +6,7 @@ module AdaptiveAlias
6
6
  attr_reader :fix_association
7
7
  attr_reader :fix_missing_attribute
8
8
  attr_reader :removed
9
+ attr_reader :removable
9
10
 
10
11
  def initialize(klass, old_column, new_column)
11
12
  @klass = klass
@@ -15,39 +16,65 @@ module AdaptiveAlias
15
16
 
16
17
  def add_hooks!(current_column:, alias_column:, log_warning: false)
17
18
  patch = self
19
+ klass = @klass
18
20
  old_column = @old_column
19
21
  new_column = @new_column
20
22
 
21
- AdaptiveAlias.get_or_create_model_module(@klass).instance_exec do
23
+ AdaptiveAlias.get_or_create_model_module(klass).instance_exec do
22
24
  remove_method(new_column) if method_defined?(new_column)
23
25
  define_method(new_column) do
24
- AdaptiveAlias.rescue_missing_attribute{ self[new_column] }
26
+ AdaptiveAlias.rescue_missing_attribute(klass){ self[new_column] }
27
+ end
28
+
29
+ remove_method("#{new_column}=") if method_defined?("#{new_column}=")
30
+ define_method("#{new_column}=") do |*args|
31
+ AdaptiveAlias.rescue_missing_attribute(klass){ super(*args) }
25
32
  end
26
33
 
27
34
  remove_method(old_column) if method_defined?(old_column)
28
35
  define_method(old_column) do
29
36
  patch.log_warning if log_warning
30
- AdaptiveAlias.rescue_missing_attribute{ self[old_column] }
37
+ AdaptiveAlias.rescue_missing_attribute(klass){ self[old_column] }
38
+ end
39
+
40
+ remove_method("#{old_column}=") if method_defined?("#{old_column}=")
41
+ define_method("#{old_column}=") do |*args|
42
+ patch.log_warning if log_warning
43
+ AdaptiveAlias.rescue_missing_attribute(klass){ super(*args) }
31
44
  end
32
45
  end
33
46
 
34
- expected_error_message = "Mysql2::Error: Unknown column '#{@klass.table_name}.#{current_column}' in 'where clause'".freeze
47
+ expected_association_err_msgs = [
48
+ "Mysql2::Error: Unknown column '#{klass.table_name}.#{current_column}' in 'where clause'".freeze,
49
+ "Mysql2::Error: Unknown column '#{current_column}' in 'field list'".freeze,
50
+ ].freeze
35
51
 
36
- @fix_missing_attribute = proc do
52
+ expected_attribute_err_msgs = [
53
+ "can't write unknown attribute `#{current_column}`".freeze,
54
+ "missing attribute: #{current_column}".freeze,
55
+ ].freeze
56
+
57
+ @fix_missing_attribute = proc do |error_klass, error|
58
+ next false if not patch.removable
37
59
  next false if patch.removed
60
+ next false if klass != error_klass
61
+ next false if not expected_attribute_err_msgs.include?(error.message)
38
62
 
39
63
  patch.remove!
40
64
  next true
41
65
  end
42
66
 
43
67
  @fix_association = proc do |target, error|
44
- next false if patch.removed || error.message != expected_error_message
68
+ next false if not patch.removable
69
+ next false if patch.removed
70
+ next false if not expected_association_err_msgs.include?(error.message)
45
71
 
46
72
  patch.remove!
47
73
 
48
74
  if target
49
75
  hash = target.where_values_hash
50
76
  hash[alias_column] = hash.delete(current_column) if hash.key?(current_column)
77
+ hash[alias_column.to_s] = hash.delete(current_column.to_s) if hash.key?(current_column.to_s)
51
78
  target.instance_variable_set(:@arel, nil)
52
79
  target.unscope!(:where).where!(hash)
53
80
  end
@@ -57,7 +84,7 @@ module AdaptiveAlias
57
84
  end
58
85
 
59
86
  def log_warning
60
- if @prev_warning_time == nil || @prev_warning_time < AdaptiveAlias.log_interval.ago
87
+ if @prev_warning_time == nil || @prev_warning_time < Time.now - AdaptiveAlias.log_interval
61
88
  @prev_warning_time = Time.now
62
89
  AdaptiveAlias.unexpected_old_column_proc&.call
63
90
  end
@@ -65,11 +92,15 @@ module AdaptiveAlias
65
92
 
66
93
  def remove!
67
94
  @removed = true
68
- @klass.send(:reload_schema_from_cache)
69
- @klass.initialize_find_by_cache
95
+ @klass.reset_column_information
96
+ @klass.columns_hash
70
97
  @fix_association = nil
71
98
  @fix_missing_attribute = nil
72
99
  end
100
+
101
+ def mark_removable
102
+ @removable = true
103
+ end
73
104
  end
74
105
  end
75
106
  end
@@ -14,7 +14,8 @@ module AdaptiveAlias
14
14
  def remove!
15
15
  super
16
16
  @klass.remove_alias_attribute(@new_column)
17
- BackPatch.new(@klass, @old_column, @new_column).apply!
17
+ @klass.define_attribute_method(@new_column)
18
+ BackwardPatch.new(@klass, @old_column, @new_column).apply!
18
19
  end
19
20
  end
20
21
  end
@@ -1,3 +1,3 @@
1
1
  module AdaptiveAlias
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,65 +1,78 @@
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/back_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::BackPatch.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
- end
65
- end
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/write_attribute'
6
+ require 'adaptive_alias/active_model_patches/remove_alias_attribute'
7
+ require 'adaptive_alias/patches/backward_patch'
8
+ require 'adaptive_alias/patches/forward_patch'
9
+
10
+ require 'adaptive_alias/hooks/association'
11
+ require 'adaptive_alias/hooks/association_scope'
12
+ require 'adaptive_alias/hooks/singular_association'
13
+ require 'adaptive_alias/hooks/relation'
14
+
15
+ module AdaptiveAlias
16
+ @log_interval = 10 * 60
17
+ @current_patches = {}
18
+ @model_modules ||= {}
19
+
20
+ class << self
21
+ attr_accessor :unexpected_old_column_proc
22
+ attr_accessor :log_interval
23
+ attr_accessor :current_patches
24
+ end
25
+
26
+ class << self
27
+ def [](old_column, new_column)
28
+ old_column = old_column.to_sym
29
+ new_column = new_column.to_sym
30
+
31
+ Module.new do
32
+ extend ActiveSupport::Concern
33
+
34
+ included do
35
+ patch = (column_names.include?(new_column) ? Patches::BackwardPatch : Patches::ForwardPatch).new(self, old_column, new_column)
36
+ patch.apply!
37
+ patch.mark_removable
38
+ end
39
+ end
40
+ end
41
+
42
+ def rescue_statement_invalid(relation, &block)
43
+ yield
44
+ rescue ActiveRecord::StatementInvalid => error
45
+ raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_association.call(relation, error) }
46
+
47
+ result = rescue_statement_invalid(relation, &block)
48
+ AdaptiveAlias.current_patches.each_value(&:mark_removable)
49
+ return result
50
+ end
51
+
52
+ def rescue_missing_attribute(klass, &block)
53
+ yield
54
+ rescue ActiveModel::MissingAttributeError => error
55
+ raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_missing_attribute.call(klass, error) }
56
+
57
+ result = rescue_missing_attribute(klass, &block)
58
+ AdaptiveAlias.current_patches.each_value(&:mark_removable)
59
+ return result
60
+ end
61
+
62
+ def get_or_create_model_module(klass)
63
+ return @model_modules[klass] if @model_modules[klass]
64
+
65
+ @model_modules[klass] = Module.new
66
+ klass.prepend(@model_modules[klass])
67
+ return @model_modules[klass]
68
+ end
69
+
70
+ def missing_value?(attributes, klass, name)
71
+ return false if attributes.key?(name)
72
+
73
+ old_name = klass.attribute_aliases.key(name)
74
+ return false if old_name == nil
75
+ return !!AdaptiveAlias.current_patches[[klass, old_name.to_sym, name.to_sym]]
76
+ end
77
+ end
78
+ 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.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - khiav reoy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-22 00:00:00.000000000 Z
11
+ date: 2022-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,19 +73,19 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '5.0'
75
75
  - !ruby/object:Gem::Dependency
76
- name: backports
76
+ name: rails_compatibility
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
79
+ - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: 3.15.0
81
+ version: 0.0.8
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - "~>"
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: 3.15.0
88
+ version: 0.0.8
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: activerecord
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -100,20 +100,6 @@ dependencies:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '3'
103
- - !ruby/object:Gem::Dependency
104
- name: rails_compatibility
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: 0.0.8
110
- type: :runtime
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: 0.0.8
117
103
  description: Extend attribute_alias and make it be adaptive with realtime database
118
104
  schema
119
105
  email:
@@ -139,11 +125,12 @@ files:
139
125
  - lib/adaptive_alias.rb
140
126
  - lib/adaptive_alias/active_model_patches/read_attribute.rb
141
127
  - lib/adaptive_alias/active_model_patches/remove_alias_attribute.rb
128
+ - lib/adaptive_alias/active_model_patches/write_attribute.rb
142
129
  - lib/adaptive_alias/hooks/association.rb
143
130
  - lib/adaptive_alias/hooks/association_scope.rb
144
131
  - lib/adaptive_alias/hooks/relation.rb
145
132
  - lib/adaptive_alias/hooks/singular_association.rb
146
- - lib/adaptive_alias/patches/back_patch.rb
133
+ - lib/adaptive_alias/patches/backward_patch.rb
147
134
  - lib/adaptive_alias/patches/base.rb
148
135
  - lib/adaptive_alias/patches/forward_patch.rb
149
136
  - lib/adaptive_alias/version.rb