【发布时间】:2012-01-18 06:06:51
【问题描述】:
假设我有一个基本的 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 的 cmets。典型的处理方式是什么?
更新:根据 Nicholas 的建议,这里有一个 save_with_cmets 的实现,它可以工作但很丑:
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 可能是正确的,因为最好避免尝试进行级联保存并使用嵌套属性解决方案。我会让这个开放一段时间,看看是否有人有任何其他建议。
【问题讨论】:
标签: ruby-on-rails ruby