Skip to content

Commit

Permalink
Merge pull request #811 from Shopify/accomodate-rails-attribute_metho…
Browse files Browse the repository at this point in the history
…d_matchers-rename

Handle attribute_method_matchers rename to attribute_method_patterns
  • Loading branch information
Morriar authored Feb 11, 2022
2 parents 612ae60 + aa45350 commit c52f42b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
30 changes: 18 additions & 12 deletions lib/tapioca/dsl/compilers/active_model_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,32 @@ def gather_constants

sig { params(constant: ::ActiveModel::Attributes::ClassMethods).returns(T::Array[[::String, ::String]]) }
def attribute_methods_for(constant)
constant.attribute_method_matchers.flat_map do |matcher|
patterns = if constant.respond_to?(:attribute_method_patterns)
# https://github.com/rails/rails/pull/44367
T.unsafe(constant).attribute_method_patterns
else
constant.attribute_method_matchers
end
patterns.flat_map do |pattern|
constant.attribute_types.map do |name, value|
next unless handle_method_matcher?(matcher)
next unless handle_method_pattern?(pattern)

[matcher.method_name(name), type_for(value)]
[pattern.method_name(name), type_for(value)]
end.compact
end
end

sig do
params(matcher: ::ActiveModel::AttributeMethods::ClassMethods::AttributeMethodMatcher)
.returns(T::Boolean)
end
def handle_method_matcher?(matcher)
target = if matcher.respond_to?(:method_missing_target)
sig { params(pattern: T.untyped).returns(T::Boolean) }
def handle_method_pattern?(pattern)
target = if pattern.respond_to?(:method_missing_target)
# Pre-Rails 6.0, the field is named "method_missing_target"
T.unsafe(matcher).method_missing_target
else
T.unsafe(pattern).method_missing_target
elsif pattern.respond_to?(:target)
# Rails 6.0+ has renamed the field to "target"
matcher.target
pattern.target
else
# https://github.com/rails/rails/pull/44367/files
T.unsafe(pattern).proxy_target
end

HANDLED_METHOD_TARGETS.include?(target.to_s)
Expand Down
10 changes: 8 additions & 2 deletions lib/tapioca/dsl/compilers/active_record_columns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,14 @@ def decorate(root, constant)
constant.attribute_aliases.each do |attribute_name, column_name|
attribute_name = attribute_name.to_s
column_name = column_name.to_s
new_method_names = constant.attribute_method_matchers.map { |m| m.method_name(attribute_name) }
old_method_names = constant.attribute_method_matchers.map { |m| m.method_name(column_name) }
patterns = if constant.respond_to?(:attribute_method_patterns)
# https://github.com/rails/rails/pull/44367
T.unsafe(constant).attribute_method_patterns
else
constant.attribute_method_matchers
end
new_method_names = patterns.map { |m| m.method_name(attribute_name) }
old_method_names = patterns.map { |m| m.method_name(column_name) }
methods_to_add = new_method_names - old_method_names

add_methods_for_attribute(mod, constant, column_name, attribute_name, methods_to_add)
Expand Down
2 changes: 2 additions & 0 deletions sorbet/rbi/shims/activemodel.rbi
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# typed: true

module ActiveModel::Attributes::ClassMethods
requires_ancestor { Kernel }

sig { returns(T::Hash[String, ActiveModel::Type::Value]) }
def attribute_types; end

Expand Down

0 comments on commit c52f42b

Please sign in to comment.