application record: add array_attribute method.

Add `array_attribute` method that defines helper methods for converting
array attributes to or from strings.
This commit is contained in:
evazion
2018-11-13 16:25:45 -06:00
parent a57d4a9558
commit b660aeefd7
5 changed files with 37 additions and 16 deletions

View File

@@ -269,6 +269,37 @@ 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