验证关联对象(延迟验证)

时间:2016-11-24 13:54:25

标签: ruby-on-rails validation associations

我正在尝试用条件解决相关对象的验证。

在作者之前,用户无需填写author_bio。因此,应用需要确保,如果用户已经创建了任何帖子,则该作者无法创建没有author_bio的帖子,并且author_bio无法删除。

class User < ApplicationRecord
  has_many :posts, foreign_key: 'author_id', inverse_of: :author

  validates :author_bio, presence: { if: :author? }

  def author?
    posts.any?
  end 
end

class Post < ApplicationRecord
  belongs_to :author, class_name: 'User', inverse_of: :posts, required: true
end

不幸的是,这并没有在创建新帖子时验证作者:

user = User.first
user.author_bio
=> nil

post = Post.new(author: user)
post.valid?
=> true
post.save
=> true
post.save
=> false
post.valid?
=> false

那么如何在没有author_bio的情况下阻止用户创建新帖子?我可以向Post模型添加第二个验证,但这不是DRY。有没有更好的解决方案?

1 个答案:

答案 0 :(得分:0)

这里的答案似乎是使用inverse_of一旦你正确设置了你的关联(包括你拥有的class User < ApplicationRecord has_many :posts, foreign_key: 'author_id', inverse_of: :author validates :author_bio, presence: { if: :author? } def author? posts.any? end end class Post < ApplicationRecord belongs_to :author, class_name: 'User', inverse_of: :posts validates :author, presence: true validates_associated :author end ,但是说明其他人,在许多情况下,rails会错过它们或者错误地创建它们)

所以要在这里调整课程:

user = User.first
user.author_bio
=> nil

post = Post.new(author: user)
post.valid?
=> false
post.save
=> false

现在,当您尝试运行之前所做的事情时:

author_bio

由于User为空

,因此不允许保存

唯一需要注意的是设置正确的关联,否则rails会混淆并跳过required: true类的验证,因为它认为这种关系尚未存在。

注意:我从belongs_to删除了validates :author, presence: true,因为在rails 5中是默认值,因此您只需要在rails 5中不需要class Product { /** * @ORM\Column(type="string", nullable=true) * * @Assert\Image */ private $image; }