Я хочу улучшить сеттеры ActiveRecord в Rails, чтобы гарантировать сохранение только допустимых значений.Одним из таких мест, где это необходимо, являются номера телефонов.Пользователь может вводить телефонный номер в различных форматах, таких как
(123) 456-7890
+1 123-456-7890
, но я хочу сохранить цифры и отбросить остальные, когда он поступит в базу данных.Подход, который я использую сейчас, заключается в переопределении методов установки с использованием alias_method
.Кроме того, я пытаюсь поместить это в модуль, чтобы любой класс модели, который содержит номер телефона, мог включать этот модуль и определять поля, которые должны быть очищены.Тип интерфейса, который я надеюсь использовать:
# Person has a "phone" attribute to store phone numbers
class Person < ActiveRecord::Base
# first include this module
include PhoneSanitizer
# then call the class method and tell it which
# fields need need to be sanitized
sanitize_phone_field :phone
end
Единственное, что я делаю в своих классах модели, - это включаю модуль PhoneSanitizer
(который добавляет метод класса - sanitize_phone_field
вPerson
класс).Этот метод теперь отвечает за переопределение метода setter phone=
.Это часть, которую я не получил работать.
module PhoneSanitizer
module ClassMethods
# wrap each of the passed-in fields with setters that
# clean up the phone number value of non-digits.
def sanitize_phone(*fields)
fields.each do |field|
new_method = "original_#{field}=".to_sym
original_method = "#{field}=".to_sym
alias_method new_method, original_method
define_method(original_method) do |value|
self.send(new_method, phone_to_number(value))
end
end
end
end
def self.included(base)
base.extend(ClassMethods)
end
def phone_to_number(number)
number.gsub(/[^\d]/, '')
end
end
Когда вызывается sanitize_phone
, выдается ошибка, говорящая, что :phone=
не определен для класса Person
, и это имеет смысл,Как мне вместо этого использовать псевдоним метода для экземпляров Person?