ActiveRecord: сделайте так, чтобы перед сохранением во всех текстовых полях использовалась полоска, если не указано иное - PullRequest
5 голосов
/ 27 июня 2011

В течение многих лет я сталкивался с различными проблемами на разных сайтах, когда пользователи ставили пробелы в начале / конце строковых и текстовых полей. Иногда это вызывает проблемы форматирования / макета, иногда они вызывают проблемы с поиском (то есть, порядок поиска выглядит неправильно, хотя это не так), иногда они фактически приводят к сбою приложения.

Я подумал, что было бы полезно вместо того, чтобы вставлять несколько обратных вызовов before_save, как я делал в прошлом, добавить некоторые функции в ActiveRecord для автоматического вызова .strip в любых строковых / текстовых полях перед сохранением, если только я не скажу это не так, например, с do_not_strip :field_x, :field_y или чем-то похожим в начале определения класса.

Прежде чем я пойду и пойму, как это сделать, кто-нибудь видел лучшее решение? Просто чтобы быть ясно, я уже знаю, что я могу сделать это:

before_save :strip_text_fields

def strip_text_fields
  self.field_x.strip!
  self.field_y.strip!
end

но я ищу более хороший способ.

ура, максимум

Ответы [ 3 ]

10 голосов
/ 27 июня 2011

Вот удобный модуль, который вы можете добавить в lib и включить в свои модели.Он не имеет исключений, которые вы упомянули, но ищет метод strip!, который может быть достаточно хорошим.Вы можете добавить функцию исключений довольно легко, если это необходимо.

# lib/attribute_stripping.rb
module AttributeStripping

  def self.included(context)
    context.send :before_validation, :strip_whitespace_from_attributes
  end

  def strip_whitespace_from_attributes
    attributes.each_value { |v| v.strip! if v.respond_to? :strip! }
  end

end

Использовать так:

class MyModel < ActiveRecord::Base
    include AttributeStripping

    # ...
end

ОБНОВЛЕНИЕ (9/10/2013):

Возвращаясь к этому ответу пару лет спустя, я вижу, как изменились ветры.Есть более чистый способ сделать это сейчас.Создайте модуль, подобный следующему:

module AttributeStripper

  def self.before_validation(model)
    model.attributes.each_value { |v| v.strip! if v.respond_to? :strip! }
    true
  end

end

и установите его метод, который будет вызываться в нужное время в вашей модели:

class MyModel < ActiveRecord::Base
  before_validation AttributeStripper

  # ...
end

Этот модуль легче протестировать, поскольку он не смешан.

2 голосов
/ 27 июня 2011

Я имел дело с такого рода проблемами целостности данных в различных приложениях.

Я использовал для манипулирования вводом таким образом.

Но теперь лучший совет, который я на самом деле видел и следовалхранить все, что пользователь вводитЗатем выполните постобработку на бэкэнде, чтобы сделать полосу.Создайте дополнительные поля базы данных (destripped), если вы действительно хотите это в таблице модели базы данных.

Основная причина этого одна (основная) вещь - когда пользователи хотят пересмотреть свои данные, то есть отредактировать, оникак правило, вы ожидаете увидеть, что они набрали. Вторая причина заключается в том, что вы избежите вероятности того, что ваша полоса не будет работать правильно и либо испортит данные, либо фактически выдаст ошибку.

1 голос
/ 27 июня 2011

Я написал для этой цели плагин . Я не пробовал это некоторое время, и у него нет тестов - так что нет никаких гарантий, что он все еще работает. Верхом будет чистая модель:

class Story < ActiveRecord::Base
  strip_strings :title, :abstract, :text
end
...