Fix conflict between normalize and array_attribute macros.
Fix the `normalize` and `array_attribute` macros conflicting with each other on the WikiPage model. This meant code like `wiki_page.other_names = "foo bar"` didn't work. Both macros defined a `other_names=` method, but one method overrode the other. The fix is to use anonymous modules and prepend so we can chain method calls with super.
This commit is contained in:
@@ -4,6 +4,7 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
include Deletable
|
||||
include Mentionable
|
||||
include Normalizable
|
||||
include ArrayAttribute
|
||||
extend HasBitFlags
|
||||
extend Searchable
|
||||
|
||||
@@ -157,37 +158,6 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
concerning :AttributeMethods do
|
||||
class_methods do
|
||||
# Defines `<attribute>_string`, `<attribute>_string=`, and `<attribute>=`
|
||||
# methods for converting an array attribute to or from a string.
|
||||
#
|
||||
# The `<attribute>=` setter parses strings into an array using the
|
||||
# `parse` regex. The resulting strings can be converted to another type
|
||||
# with the `cast` option.
|
||||
def array_attribute(name, parse: /[^[:space:]]+/, cast: :itself)
|
||||
define_method "#{name}_string" do
|
||||
send(name).join(" ")
|
||||
end
|
||||
|
||||
define_method "#{name}_string=" do |value|
|
||||
raise ArgumentError, "#{name} must be a String" unless value.respond_to?(:to_str)
|
||||
send("#{name}=", value)
|
||||
end
|
||||
|
||||
define_method "#{name}=" do |value|
|
||||
if value.respond_to?(:to_str)
|
||||
super value.to_str.scan(parse).map(&cast)
|
||||
elsif value.respond_to?(:to_a)
|
||||
super value.to_a
|
||||
else
|
||||
raise ArgumentError, "#{name} must be a String or an Array"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def warnings
|
||||
@warnings ||= ActiveModel::Errors.new(self)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user