Rails设置name与code字段非空后仍允许空值,求排查原因
问题描述
我使用如下迁移创建products表:
class CreateProducts < ActiveRecord::Migration[7.0] def change create_table :products do |t| t.string :name t.string :code t.integer :gtin t.references :supplier, null: false, foreign_key: true t.references :group, null: false, foreign_key: true t.timestamps end end end
由于不希望name和code字段接受空值,我创建了如下修改迁移:
class ChangeNameAndCodeToNotNullInProducts < ActiveRecord::Migration[7.0] def change change_column :products, :name, :string, null: false change_column :products, :code, :string, null: false end end
但在产品表单中提交空数据时,仍能成功创建产品。请问我遗漏了什么?
解决方法
你遗漏了Rails模型层的验证。数据库层面的NOT NULL约束仅会拦截NULL值,但表单提交的空数据会被Rails自动转换成空字符串"",这不属于NULL,所以数据库约束不会生效。同时Rails默认不会主动触发数据库约束检查,只有当数据库抛出错误时才会回滚操作,这就导致空数据能绕过约束创建产品。
你需要在Product模型中添加验证规则,确保name和code既不能为nil也不能是空字符串:
class Product < ApplicationRecord validates :name, :code, presence: true end
额外注意事项:
- 如果执行修改迁移前,
products表中已经存在name或code为空的旧数据,迁移会执行失败,需要先清理这些无效数据再运行迁移。 - 数据库约束是最后一道防线,模型验证则是在应用层提前拦截无效数据,两者结合才能彻底避免空值问题。
内容的提问来源于stack exchange,提问作者Diogo Amaral
相关产品推荐
相关产品推荐

