1

我有 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。

我试图交换构建和新方法。它的结果与构建相同。在我们的应用程序中发现了类似的行为。这是预期的行为还是我做错了什么?

4

2 回答 2

2

这对我来说似乎是预期的行为。

通过http://guides.rubyonrails.org/association_basics.html#belongs_to-association-reference

4.1.1.3 build_association(属性 = {})

build_association 方法返回关联类型的新对象。该对象将从传递的属性中实例化,并 设置通过该对象的外键的链接,但尚未保存关联的对象。

当您调用时@post.comments.build(...),Rails:

  1. 创建一个新Comment对象
  2. 设置comment.post_id@post.id
  3. 将其插入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
于 2013-02-06T05:15:20.577 回答
0

我在使用 rails 3.2 时遇到了类似的问题

首先,您需要在控制器中创建两个单独的方法。它们将如下所示:

  1. 用于使用“build_association”构建评论的“新”方法

    def new
        @post = Post.new
        comment = @post.build_comments
    end
    
  2. 使用“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

于 2017-02-14T09:53:32.910 回答