2016-11-24 101 views
2

我试图解决与条件关联对象的验证。验证关联对象(延迟验证)

直到他是作者为止,用户不需要填写author_bio。因此,应用程序需要确保,如果用户已经创建了任何帖子,那么作者无法创建帖子,如果没有author_bioauthor_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模型中添加第二个验证,但这不是干的。有没有更好的解决方案?

回答

0

答案在这里似乎是使用validates_associated一旦你有你的协会设置正确(包括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 

现在,当您尝试运行你做了什么之前:

user = User.first 
user.author_bio 
=> nil 

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

不允许你保存,因为author_bio是空

只有一点需要注意的还有树立正确的关联,否则轨感到困惑和User类跳过验证,因为它认为的关系尚不存在。

注:我在轨移除从belongs_torequired: true因为5是默认的,所以你也不会只在轨需要validates :author, presence: true 5.