如何强制rails存储空字符串?

时间:2013-07-17 16:46:06

标签: ruby-on-rails-3

我问的是question to force empty strings to be NULL;相反,我希望将空字符串的字段存储为空字符串。我想这样做的原因(即使在矛盾to what some people say中)是我希望对表适用于多种数据库类型(postgres,mysql等)的表有一个部分唯一性约束,如{{3}所述}。

架构的伪代码基本上是:

Person {
  first_name : String, presence: true
  middle_name : String, presence: true
  last_name : String, presence: true
  birth_date : String, presence: true
  city_of_birth: String, presence: true
  active: tinyint
}

约束是一个人在活跃时必须是唯一的;不活跃的人可能不是唯一的(即,我可以有多个不活跃的John Smiths,但只有一个活跃的John Smith)。

更复杂:根据项目规范,用户只需要给出first_name和last_name,其他所有字段都可以为空。

我们当前应用部分唯一性约束的解决方案是使用NULL!= NULL这一事实,如果有人未处于活动状态,则将活动tinyint设置为NULL,如果它们处于活动状态,则将其设置为1。因此,我们可以在迁移中使用此rails代码:

add_index :Persons, [first_name, middle_name, last_name, birth_date, 
  city_of_birth, active], unique:true, name: "unique_person_constraint"

但是,为了使此约束起作用,其他任何字段都不能为NULL。如果是,那么两个没有其他填充字段且active = 1的John Smiths仍将是“唯一”的,因为值为NULL的middle_name字段将彼此不同(因为NULL!= NULL,无论列类型如何)。

但是,当我这样做时

options = { first_name: "John",
  middle_name: "", 
  last_name: "Smith",
  birth_date: "",
  city_of_birth: "",
}
person = Person.new(options)
success = person.valid?

success总是假的,因为

Middle name can't be blank
City of birth can't be blank
Birth date can't be blank

所以我需要一种方法来确保我总是至少为其他字段设置空字符串来强制执行部分唯一性约束。我怎样才能做到这一点?如果我摆脱了模型定义中的presence:true,那么现在似乎允许使用NULL字段,这很糟糕。

这是Rails 3.2.13,如果需要,我可以提供其他宝石和宝石版本。

1 个答案:

答案 0 :(得分:0)

除了存在为true,您还可以将allow_blank添加为true,这样可以保存空字符串。