繁体   English   中英

在Rails中进行设置时,验证关联的模型是否存在

[英]Validate that the associated model exists when set in Rails

假设我们在Rails中具有以下Post模型:

class Post < ActiveRecord::Base
  belongs_to :user
end

user不是必需的,但是在设置用户名后,我们希望它成为有效的关联(我们不希望发布的帖子中的user_id不在数据库中)。 测试失败:

expect(Post.new).to be_valid
expect(Post.new(user_id: 0)).not_to be_valid
expect(Post.new(user: User.create)).to be_valid

一种解决方案是:

validates_presence_of :user, unless: "user_id.nil?"

这将完成所需的任务,但并不是很漂亮,因为我们不想为应用程序中的每个belongs_to编写它。

有没有办法告诉Rails检查关联模型的存在? 这不是我们默认想要的东西吗? (为什么我们要一个不指向任何东西的association_id ?)

为了确保关联在数据库级别有效,MySQL和PostgreSQL能够强制表上外键列的有效性。 从Rails 4.2开始 ,可以在迁移过程中创建这些外键约束。

您可以在迁移中至少以两种方式执行此操作。 要么将foreign_key属性传递给add_reference

add_reference :posts, :user, index: true, foreign_key: true

或在add_reference加上add_foreign_key ,这也使您可以选择在删除用户时重置密钥:

add_reference :posts, :user, index: true
add_foreign_key :posts, :user, on_delete: :nullify

通过将哈希传递给add_referenceforeign_key属性来组合两种方法(从Rails 4.2.1开始):

add_reference :posts, :user, index: true, foreign_key: {on_delete: :nullify}

如果查询通过更新user_id以指向不存在的用户来打破外键约束,则查询将失败并在Rails中引发异常。

如前所述,您还可以创建一个验证以在创建Post之前检查User存在。 但是,这不能像数据库上的外键约束那样有力的保证,因为可以在通过验证和创建Post之间的时间内删除User

为了帮助保持引用在应用程序级别上的有效性,通常最好的做法是避免将用户ID直接传递给Post构造函数。 而是尝试始终使用User对象作为输入,例如通过调用User.find(:id)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM