记录下踩过的一个坑:
类A与类B存在一对多关系,需要校验在创建b时,a存在,分别使用validates_presence_of :a 与 validates_presence_of :a_id,会发现当a尚未保存时,前者会成功创建b,后者则不行。
看个简单的例子:
group 与post 之间是一对多关系, post含字段group_id。
### app/models/post.rb
class Post < ApplicationRecord
belongs_to :group, optional: true
## 为了方便找出两者的差异,这里使用optional: true,post创建时,group_id可为nil
validates :content, presence: true
end
#### app/models/group.rb
class Group < ApplicationRecord
belongs_to :user
has_many :posts
validates :title, presence: true
end
此时,在终端执行:
post = Post.new(content: "this is a post")
post.save
# => true
接下来分别 validates_presence_of :group_id
和validates_presence_of :group
来给post添加有效性校验,要求group必须存在。
在post.rb中添加
validates_presence_of :group_id
进入console,执行如下代码:
post = Post.new(content: "my post") post.save #=> rollback, 返回false, Validation failed: Group can't be blank group = Group.new(title: "hello", user_id: User.first.id) post = Post.new(content: "my post") post.group = group post.save #=> rollback, 返回false post.save! #=> rollback, 显示 Validation failed: Group can't be blank
第一次创建post,没有给到group,无法新建,正常。
第二次创建post,使用post.group = group 给post的group赋值, 但是,你会发现虽然post.group有记录,不为nil, 但是post.group_id 依然为nil,保存时,校验group_id,为nil, 报错。
在post.rb中添加
validates_presence_of :group
post = Post.new(content: "my post") post.save #=> rollback, 返回false, Validation failed: Group can't be blank group = Group.new(title: "hello", user_id: User.first.id) post = Post.new(content: "my post") post.group = group post.save #=> 返回true, 依次在Group,Post中插入了一条新的记录
第一次创建post,没有给到group,无法新建,正常,同
validates_presence_of :group_id
的效果一样。第二次创建post,使用post.group = group 给post的group赋值,此时,虽然post.group_id 依然为nil,但是由于post.group不为nil,检验通过,group存在,成功创建。
很显然,当我们创建post时,需要检验group必须存在,并不要求此时group已经创建,后者才是我们需要的校验方式。