2011-01-06 59 views
2

我正在使用的数据源非常糟糕。有些地方你会期望整数,你会得到“三”。在电话号码字段中,您可能会收到“电话号码是xxx”。有些字段只是空白。使用'故意'无效数据对模型进行验证

这是好的,因为我解析每个字段,所以“三”将在我的模型中以整数3结尾,电话号码(等)将通过正则表达式提取。该服务的用户知道数据是粗略和不完整的,因为这是我们的数据源维护方式的一个不幸事实,我们无法做到这一点,但加紧了我们的解析游戏!另外,我们在解析越来越多的原始数据时,正在慢慢制作自己的数据版本,但这个可怜的数据源现在需要做。

因此,用户选择他们希望解析的数据,并且我们尽我们所能,返回一个部分/不正确的模型。现在我们要存储的最终模型应该得到验证 - 有些字段不能为空,某些字符串必须遵守格式等等。

该应用的流程为:

  1. 用户告诉哪个数据服务到 解析。
  2. 服务关闭并抓取 的数据,解析它可以和 返回一个部分模型与 无论它可以检索的任何数据。
  3. 我们向用户显示数据, 允许他们进行更正 并填写任何未收集数据的必填字段 。
  4. 这个用户更正的数据将被保存,因此被验证为 。
  5. 如果验证失败,再次显示数据 供用户修复,冲洗& 重复。

什么是最好的方式去让模型开始可能完全无效或不包含数据,但最终需要验证?这两个方面,我认为(和部分实现)是:

  1. 2模型 - 一个数据模型,其中有验证等,以及UnconfirmedData模型,它没有验证。将原始数据放入UnconfirmedData模型中,直到用户进行更正为止,然后将其放入数据模型并尝试进行验证。
  2. 一个模型,带有“确认数据”标志,验证是手动执行的,而不是Rails的验证。

在实践中我倾向于使用2种型号瘦,但我很新到Rails,所以我觉得有我是做一个更好的方式,Rails有奇怪我这样:)

回答

2
的习惯

您必须在请求之间保存数据吗?如果是这样,我会使用你的两种模型格式,但使用单表继承(STI)来保持干燥。

第一个模型,负责解析,渲染和做最好的它可以,不应该有任何验证或限制保存它。但是,它应该在迁移中有type列,以便您可以使用继承的优点。如果你不知道我在说什么,请阅读关于性传播疾病的大量信息,一个好的起点是a definitive guide

第二个模型将是您在应用程序的其余部分使用的模型,即严格模型,其中包含所有验证的模型。每次用户提交重做的数据和可能有效的数据时,应用程序都会尝试将从params创建的开放模型实例移动到第二个模型的实例,并查看它是否有效。如果是这样,将它保存到数据库中,并且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 2011-01-08 16:10:19

2

使用一个模型应该足够简单。您需要一个属性/方法来确定是否应该执行验证。你可以通过:if =>绕过/让他们:

validates_presence_of :title, :if => :should_validate 

should_validate可以是简单的布尔属性,当模型实例是“临时”返回false,或者如果需要更复杂的方法。

+0

啊,这就是我期待的Rails善良。然而,在实施了这个方法和我上面列出的方法之后,我想我会走下2条路线。这不是很光滑,但可以让我更好地从临时数据中分离有效的数据,这对未来可能很重要。非常感谢你的答复,但我没有看到:如果以前,毫无疑问它很快就会有用。 – Richter 2011-01-08 16:08:11