我有2个模型,如下所示
Class Post
has_many :comments, :dependent => :destroy
end
Class Comment
validates_presence_of :post
validates_presence_of :comment
belongs_to :post
end
在评论控制器中,
def create
comment = @post.comments.build(params[:comment])
if comment.save
// some code
else
// some code
end
end
根据验证评论无效时,评论不会保存。但是当在视图中访问@post对象时,它包含一个带有nil id的注释对象。这在Rails 2.3.11中没有发生。我们升级到Rails 3.1,然后升级到Rails 3.2。当我执行@ post.reload时,这个带有nil id的注释对象消失了。我们正在使用REE。
我试图交换构建和新方法。它与build具有相同的结果。我们的应用程序中发现了类似的行为这是预期的行为,还是我做错了什么?
答案 0 :(得分:2)
这对我来说似乎是预期的行为。
通过http://guides.rubyonrails.org/association_basics.html#belongs_to-association-reference
4.1.1.3 build_association(attributes = {})
build_association方法返回关联的新对象 类型。此对象将从传递的属性中实例化,并且 通过此对象的外键的链接将被设置,但是 相关对象尚未保存。
当你致电@post.comments.build(...)
时,Rails:
Comment
对象comment.post_id
设置为@post.id
。comments
数组(内存中)。验证失败时,它不会删除注释,并且注释会在内存中的注释数组中保留。当@post
进入您的观点时,@post.comments
仍会包含经过严格验证的评论。
关于如何处理它,我不确定。也许你可以做一些像(在你的控制器中)......(虽然觉得很难看。)
def create
comment = @post.comments.build(params[:comment])
if comment.save
// some code
else
@bad_comment = @post.comments.pop
end
end
答案 1 :(得分:0)
使用rails 3.2时遇到了类似的问题
首先,您需要在控制器中创建两个单独的方法。他们将如下:
使用'build_association'构建评论的'新'方法
def new
@post = Post.new
comment = @post.build_comments
end
使用'create_association'实际创建评论的'创建'方法
def create
@post = Post.new(params[:post])
comment = @post.create_comments(params[:post][:comment_attributes])
if comment.save
// some code
else
@bad_comment = @post.comments.pop
end
end
注意:我建议使用'fields_for'通过表单将'comment'属性作为'post'的嵌套属性传递。
请参阅: http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html