Проверка на модели с «преднамеренными» неверными данными - PullRequest
2 голосов
/ 06 января 2011

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

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

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

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

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 06 января 2011

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

validates_presence_of :title, :if => :should_validate

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

2 голосов
/ 06 января 2011

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

Первая модель, отвечающая за разбор и рендеринг и делающая все возможное, не должна иметь никаких проверок или ограничений на ее сохранение. Тем не менее, он должен иметь столбец type в миграции, чтобы вы могли использовать свойства наследования. Если вы не знаете, о чем я говорю, прочитайте о богатстве информации о ИППП, для начала неплохо было бы начать с .

Вторая модель будет той, которую вы будете использовать в остальной части приложения, строгая модель, которая имеет все проверки. Каждый раз, когда пользователь отправляет переработанные и потенциально допустимые данные, ваше приложение будет пытаться переместить ваш экземпляр открытой модели, созданной из параметров, в экземпляр второй модели и посмотреть, была ли она действительной. Если это так, сохраните его в базе данных, и атрибут 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, чтобы вернуть только действительные.

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

...