gpt4 book ai didi

ruby-on-rails - 如何验证属于与 Rails 关联的存在?

转载 作者:数据小太阳 更新时间:2023-10-29 06:33:18 25 4
gpt4 key购买 nike

假设我有一个基本的 Rails 应用程序,它具有基本的一对多关系,其中每条评论都属于一篇文章:

$ rails blog
$ cd blog
$ script/generate model article name:string
$ script/generate model comment article:belongs_to body:text

现在我添加代码来创建关联,但我还想确保在创建评论时,它总是有一篇文章:

class Article < ActiveRecord::Base
has_many :comments
end

class Comment < ActiveRecord::Base
belongs_to :article
validates_presence_of :article_id
end

现在假设我想同时创建一篇带有评论的文章:

$ rake db:migrate
$ script/console

如果你这样做:

>> article = Article.new
=> #<Article id: nil, name: nil, created_at: nil, updated_at: nil>
>> article.comments.build
=> #<Comment id: nil, article_id: nil, body: nil, created_at: nil, updated_at: nil>
>> article.save!

你会得到这个错误:

ActiveRecord::RecordInvalid: Validation failed: Comments is invalid

这是有道理的,因为评论还没有 page_id。

>> article.comments.first.errors.on(:article_id)
=> "can't be blank"

因此,如果我从 comment.rb 中删除 validates_presence_of :article_id,那么我可以进行保存,但这也将允许您创建没有文章 ID 的评论.处理此问题的典型方法是什么?

更新:根据 Nicholas 的建议,这里有一个 save_with_comments 的实现,它可以工作但很丑陋:

def save_with_comments
save_with_comments!
rescue
false
end

def save_with_comments!
transaction do
comments = self.comments.dup
self.comments = []
save!
comments.each do |c|
c.article = self
c.save!
end
end
true
end

不确定我是否要为每个一对多关联添加这样的内容。 Andy 可能是正确的,因为最好避免尝试进行级联保存并使用嵌套属性解决方案。我会把这个打开一段时间,看看是否有人有任何其他建议。

最佳答案

我也一直在研究这个话题,这里是我的总结:

为什么这在 OOTB 中不起作用(至少在使用 validates_presence_of :article 而不是 validates_presence_of :article_id 时)的根本原因是 rails 不使用一个内部的恒等映射,因此它自己不会知道 article.comments[x].article == article

我已经找到了三个解决方法,只需稍加努力即可使其正常工作:

  1. 在创建评论之前保存文章(rails 会自动将保存期间生成的文章 ID 传递给每个新创建的评论;参见 Nicholas Hubbard 的回复)
  2. 在创建评论后明确设置文章(参见 W. Andrew Loe III 的回复)
  3. 使用 inverse_of:
    class Article < ActiveRecord::Base
    has_many :comments, :inverse_of => :article
    end

最后一个解决方案是本文中提到的机器人,但似乎是 Rails 针对缺少标识映射的快速修复解决方案。在我看来,它也是三者中干扰最小的一个。

关于ruby-on-rails - 如何验证属于与 Rails 关联的存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1025292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com