2011-01-06 3 views
2

Источник данных, с которым я работаю, ужасен. В некоторых местах, где вы ожидаете целых чисел, вы получаете «Три». В поле номера телефона вы можете получить «телефон # xxx». Некоторые поля просто пусты.Проверка на модели с «преднамеренными» недопустимыми данными

Это нормально, так как я разбираю каждое поле так, что «Три» в моей модели будет целым числом 3, телефонные номера (и такие) будут извлечены через регулярное выражение. Пользователи сервиса ЗНАЮТ, что данные являются отрывочными и неполными, так как это печальный факт того, как поддерживается наш источник данных, и мы ничего не можем с этим поделать, но активируем нашу парсинговую игру! В стороне, мы производим нашу собственную версию данных медленно, поскольку мы анализируем все больше и больше исходных данных, но этот плохой источник должен сделать сейчас.

Таким образом, пользователи выбирают данные, которые они хотят проанализировать, и мы делаем все возможное, возвращая частичную/неправильную модель. Теперь окончательная модель, которую мы хотим сохранить, должна быть проверена - есть определенные поля, которые не могут быть нулевыми, некоторые строки должны придерживаться формата и так далее.

Поток приложения является:

  1. Пользователь указывает службу, данных для синтаксического анализа.
  2. Служба отключается и захватывает данные, анализирует, что она может и возвращает частичную модель с любыми данными, которые она могла бы получить.
  3. Мы показываем данные пользователю, , позволяя им вносить поправки и заполнить любые обязательные поля , по которым не было данных.
  4. Данные, скорректированные пользователем, должны быть сохранены и поэтому подтверждены.
  5. Если валидация не удалась, покажите данные повторно , чтобы пользователь мог исправить ошибки, ополаскивать & повторить.

Каков наилучший способ иметь модель, которая начинает быть потенциально полностью недействительной или не содержать данных, но которая должна быть подтверждена в конце концов? Двумя путями, о которых я думал (и частично реализованными), являются:

  1. 2 модели - модель данных с проверками и т. Д., А также модель UnconfirmedData, которая не имеет валидаций. Исходные данные помещаются в модель UnconfirmedData до тех пор, пока пользователь не внесет свои исправления, после чего он будет помещен в модель данных и будет предпринята проверка.
  2. Одна модель с флагом «подтвержденные данные», причем проверка выполняется вручную, а не проверка Rails.

На практике я склоняюсь к использованию 2 модели, но я довольно новыми для Rails, так что я думал, что мне будет лучше способ сделать это, Rails имеет привычку удивлять меня так :)

ответ

2

Должны ли вы сохранять свои данные между запросами? Если это так, я бы использовал ваш формат двух моделей, но использую Single Table Inheritance (STI), чтобы все было сухим.

Первая модель, ответственная за синтаксический анализ и рендеринг, а также за то, что она делает-лучше всего, не должна иметь никаких валидаций или ограничений при ее сохранении. Тем не менее, он должен иметь столбец type в миграции, чтобы вы могли использовать свойство наследования.Если вы не знаете, о чем я говорю, прочитайте о богатстве информации о STI, хорошим местом для начала будет a definitive guide.

Вторая модель будет той, которую вы использовали бы в остальной части приложения, строгой модели, той, которая имеет все проверки. Каждый раз, когда пользователь отправляет переработанные и потенциально достоверные данные, ваше приложение будет пытаться переместить ваш экземпляр открытой модели, созданной из параметров, в экземпляр второй модели и посмотреть, действительно ли она действительна. Если бы это было, сохраните его в базе данных, и атрибут type изменится, и все будет замечательно. Если это недопустимо, сохраните первый экземпляр и верните второй экземпляр пользователю, чтобы можно было использовать сообщения об ошибках проверки.

class ArticleData < ActiveRecord::Base 
    def parse_from_url(url) 
     # parses some stuff from the data source 
    end 
end 

class Article < ArticleData 
    validates_presence_of :title, :body 
    validates_length_of :title, :greater_than => 20 
    # ... 
end 

Для облегчения вышеуказанного процесса потребуется довольно интенсивное действие контроллера, но это не должно быть слишком сложно. В остальной части приложения убедитесь, что вы запустили свои запросы в модели Article, чтобы вернуться только к действительным.

Надеюсь, это поможет!

+0

Большое спасибо за разъяснение, я думаю, что так я пойду. Данные будут перемещаться между запросами и, возможно, даже сеансами, поэтому будет полезно хранить предварительные данные; это, вероятно, будет более важным в будущем, чем сейчас. Спасибо за ссылку railsforum, тоже очень полезно. – Richter

2

Использование одной модели должно быть достаточно простым. Вам понадобится атрибут/метод, чтобы определить, должны ли выполняться проверки. Вы можете передать :if => обойти/включить их:

validates_presence_of :title, :if => :should_validate 

should_validate может быть простой логический атрибут, который возвращает ложь, когда экземпляр модели «временный», или более сложный метод, если это необходимо.

+0

Ах, это была Rails доброта, на которую я надеялся. Однако после реализации этого и метода, описанного выше, мои hornairs, я думаю, что я собираюсь спуститься по 2-м модельным маршрутам. Это не совсем так гладко, но позволяет мне лучше отделяться от временных данных, что может быть важно для будущего. Большое спасибо за ваш ответ, хотя я не видел: если раньше, без сомнения, он скоро пригодится. – Richter

Смежные вопросы