Я хотел бы, чтобы моя модель User санировала некоторый вход прежде чем прежде чем сохранением. На данный момент некоторое простое пробельное разделение сделает. Таким образом избежать людей, регистрирующихся в "Harry" и симулировать быть "Harry", например.
Я предполагаю, что это - хорошая идея сделать это разделение перед проверкой, так, чтобы validates_uniqueness_of мог избежать случайных дубликатов.
class User < ActiveRecord::Base
has_many :open_ids
validates_presence_of :name
validates_presence_of :email
validates_uniqueness_of :name
validates_uniqueness_of :email
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
before_validation :strip_whitespace, :only => [:name, :email, :nick]
private
def strip_whitespace(value)
value.responds_to?('strip') ? value.strip : value
end
end
Однако этот код идет с ошибкой ArgumentError: неправильное количество аргументов (0 для 1). Я предположил, что обратный вызов будет передан значения.
Также: это разделяет на самом деле хорошую идею? Или если я скорее проверяю на пространстве и говорю пользователю, что "Harry" содержит недопустимые пробелы (я хочу позволить "Harry Potter", но не "Harry\s\sPotter").
Править: Как указано в комментарии, мой код является неверным (который является, почему я задавал вопрос a.o.). Удостоверьтесь, что Вы читаете принятый ответ в дополнение к моему вопросу для правильного кода и избегать тех же ошибок, которые я сделал.
Я не верю, что before_validation
так работает. Вместо этого вы, вероятно, захотите написать свой метод следующим образом:
def strip_whitespace
self.name = self.name.strip unless self.name.nil?
self.email = self.email.strip unless self.email.nil?
self.nick = self.nick.strip unless self.nick.nil?
end
Вы можете сделать его более динамичным, если хотите использовать что-то вроде self.columns
, но в этом суть.
Поскольку я пока не могу комментировать, мне придется спросить здесь: какой метод выдает ArgumentError? strip
, или responds_to?
Кроме того, .strip
удаляет только ведущие и последующие пробельные символы. Если вы хотите, чтобы "Гарри Поттер" с двумя пробелами не был принят, вам придется либо использовать регекс, либо, что проще, вызвать .split, который удаляет пробелы, и заново сконкатенировать строку с одним пробелом.
Что касается того, является ли удаление пробелов хорошей идеей, я не вижу проблемы, если речь идет только о ведущих и последующих пробельных символах. Если же между словами несколько пробелов, я бы уведомил пользователя, вместо того чтобы автоматически удалять лишние пробелы и выдавать пользователю не тот логин, который он отправил.