Merge pull request #49173 from Shopify/define-alias-attribute-methods-in-define_attribute_methods
Define alias attribute methods in `define_attribute_methods`
This commit is contained in:
commit
304f0a3c01
@ -202,8 +202,10 @@ def attribute_method_affix(*affixes)
|
||||
# person.name_short? # => true
|
||||
# person.nickname_short? # => true
|
||||
def alias_attribute(new_name, old_name)
|
||||
self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s)
|
||||
self.local_attribute_aliases = local_attribute_aliases.merge(new_name.to_s => old_name.to_s)
|
||||
old_name = old_name.to_s
|
||||
new_name = new_name.to_s
|
||||
self.attribute_aliases = attribute_aliases.merge(new_name => old_name)
|
||||
aliases_by_attribute_name[old_name] << new_name
|
||||
eagerly_generate_alias_attribute_methods(new_name, old_name)
|
||||
end
|
||||
|
||||
@ -282,7 +284,12 @@ def attribute_alias(name)
|
||||
# end
|
||||
def define_attribute_methods(*attr_names)
|
||||
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
|
||||
attr_names.flatten.each { |attr_name| define_attribute_method(attr_name, _owner: owner) }
|
||||
attr_names.flatten.each do |attr_name|
|
||||
define_attribute_method(attr_name, _owner: owner)
|
||||
aliases_by_attribute_name[attr_name.to_s].each do |aliased_name|
|
||||
generate_alias_attribute_methods owner, aliased_name, attr_name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -365,13 +372,11 @@ def undefine_attribute_methods
|
||||
attribute_method_patterns_cache.clear
|
||||
end
|
||||
|
||||
def local_attribute_aliases # :nodoc:
|
||||
@local_attribute_aliases ||= {}
|
||||
def aliases_by_attribute_name # :nodoc:
|
||||
@aliases_by_attribute_name ||= Hash.new { |h, k| h[k] = [] }
|
||||
end
|
||||
|
||||
private
|
||||
attr_writer :local_attribute_aliases # :nodoc:
|
||||
|
||||
def inherited(base) # :nodoc:
|
||||
super
|
||||
base.class_eval do
|
||||
|
@ -119,6 +119,34 @@ class AttributeMethodsTest < ActiveModel::TestCase
|
||||
ModelWithAttributes.undefine_attribute_methods
|
||||
end
|
||||
|
||||
test "#define_attribute_methods defines alias attribute methods after undefining" do
|
||||
topic_class = Class.new do
|
||||
include ActiveModel::AttributeMethods
|
||||
define_attribute_methods :title
|
||||
alias_attribute :aliased_title_to_be_redefined, :title
|
||||
|
||||
def attributes
|
||||
{ title: "Active Model Topic" }
|
||||
end
|
||||
|
||||
private
|
||||
def attribute(name)
|
||||
attributes[name.to_sym]
|
||||
end
|
||||
end
|
||||
|
||||
topic = topic_class.new
|
||||
assert_equal("Active Model Topic", topic.aliased_title_to_be_redefined)
|
||||
topic_class.undefine_attribute_methods
|
||||
|
||||
assert_not_respond_to topic, :aliased_title_to_be_redefined
|
||||
|
||||
topic_class.define_attribute_methods :title
|
||||
|
||||
assert_respond_to topic, :aliased_title_to_be_redefined
|
||||
assert_equal "Active Model Topic", topic.aliased_title_to_be_redefined
|
||||
end
|
||||
|
||||
test "#define_attribute_method does not generate attribute method if already defined in attribute module" do
|
||||
klass = Class.new(ModelWithAttributes)
|
||||
klass.send(:generated_attribute_methods).module_eval do
|
||||
|
@ -71,8 +71,10 @@ def generate_alias_attributes # :nodoc:
|
||||
generated_attribute_methods.synchronize do
|
||||
return if @alias_attributes_mass_generated
|
||||
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |code_generator|
|
||||
local_attribute_aliases.each do |new_name, old_name|
|
||||
generate_alias_attribute_methods(code_generator, new_name, old_name)
|
||||
aliases_by_attribute_name.each do |old_name, new_names|
|
||||
new_names.each do |new_name|
|
||||
generate_alias_attribute_methods(code_generator, new_name, old_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1039,6 +1039,25 @@ def name
|
||||
end
|
||||
end
|
||||
|
||||
test "#define_attribute_methods brings back undefined aliases" do
|
||||
topic_class = Class.new(ActiveRecord::Base) do
|
||||
self.table_name = "topics"
|
||||
|
||||
alias_attribute :title_alias_to_be_undefined, :title
|
||||
end
|
||||
|
||||
topic = topic_class.new(title: "New topic")
|
||||
assert_equal("New topic", topic.title_alias_to_be_undefined)
|
||||
topic_class.undefine_attribute_methods
|
||||
|
||||
assert_not_respond_to topic, :title_alias_to_be_undefined
|
||||
|
||||
topic_class.define_attribute_methods
|
||||
|
||||
assert_respond_to topic, :title_alias_to_be_undefined
|
||||
assert_equal "New topic", topic.title_alias_to_be_undefined
|
||||
end
|
||||
|
||||
test "define_attribute_method works with both symbol and string" do
|
||||
klass = Class.new(ActiveRecord::Base)
|
||||
klass.table_name = "foo"
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
class NumericalityValidationTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
NumericData.generate_alias_attributes
|
||||
@model_class = NumericData.dup
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user