【问题标题】:Validate associated object (lazy validation)验证关联对象(惰性验证)
【发布时间】:2023-03-23 06:55:01
【问题描述】:

我正在尝试使用条件解决关联对象的验证问题。

用户在成为作者之前无需填写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。有没有更好的解决方案?

【问题讨论】:

    标签: ruby-on-rails validation associations


    【解决方案1】:

    这里的答案似乎是使用validates_associated,一旦您正确设置了关联(包括您拥有的inverse_of,但对其他人来说,rails 在许多情况下会错过它们或错误地创建它们)

    所以在这里调整类:

    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
    

    现在,当您尝试运行之前的操作时:

    user = User.first
    user.author_bio
    => nil
    
    post = Post.new(author: user)
    post.valid?
    => false
    post.save
    => false
    

    不允许您保存,因为author_bio 为空

    唯一需要注意的是建立正确的关联,否则 rails 会感到困惑并跳过User 类的验证,因为它认为这种关系还不存在。

    注意:我从 belongs_to 中删除了 required: true,因为在 rails 5 中是默认设置,因此您也不需要 validates :author, presence: true,仅在 rails 5 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      • 1970-01-01
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多