如何强制rails存储空字符串



我问的问题与强制空字符串为NULL相反;相反,我希望作为空字符串的字段存储为空字符串。我之所以要这样做(甚至与一些人所说的相矛盾),是因为我希望对适用于多种数据库类型(postgres、mysql等)的表有一个部分唯一性约束,如本问题所述。

模式的伪代码基本上是:

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
}

约束条件是,如果一个人是活跃的,那么他必须是唯一的;不活跃的人可能不是唯一的(即,我可以有多个不活跃的约翰·史密斯,但只有一个活跃的约翰·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,如果需要,我可以提供其他gem和gem版本。

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

相关内容

最新更新