使用构建对象

时间:2016-01-20 06:55:34

标签: ruby-on-rails ruby ruby-on-rails-4 associations

Rails 4.2.4和Ruby 2.2.3

两个模型关联如下:

class User < ActiveRecord::Base
  has_many :documents

  accepts_nested_attributes_for :documents
end

class Document < ActiveRecord::Base
  belongs_to :user
end

用户控制器的操作如下:

class UsersController < ApplicationController
   def edit
    @user = User.find(params[:id])
    @documents = @user.documents   # List document
    @document =  @user.documents.build   # Build document
  end
end

在这里,我希望@documents变量只包含用户文档的集合。但它也附加了Document #<Document:0x007f2d28431550 id: nil, name: nil, created_at: nil, updated_at: nil, user_id: 2>的新实例,这是我不想要的。

假设@user有两个与之关联的文档。 在List Document步骤@documents变量具有以下值之后......

[#<Document:0x007f2d290b67d0
  id: 95,
  document: "doc1.pdf",
  created_at: Wed, 20 Jan 2016 04:32:16 UTC +00:00,
  updated_at: Wed, 20 Jan 2016 04:32:16 UTC +00:00,
  user_id: 2>,
#<Document:0x008f8d290e87da
  id: 96,
  document: "doc2.pdf",
  created_at: Wed, 20 Jan 2016 04:32:22 UTC +00:00,
  updated_at: Wed, 20 Jan 2016 04:32:22 UTC +00:00,
  user_id: 2>]

@documents.count = 2

但是,在Build document@documents变量之后的值如下:

[#<Document:0x007f2d290b67d0
  id: 95,
  document: "doc1.pdf",
  created_at: Wed, 20 Jan 2016 04:32:16 UTC +00:00,
  updated_at: Wed, 20 Jan 2016 04:32:16 UTC +00:00,
  user_id: 2>,
#<Document:0x008f8d290e87da
  id: 96,
  document: "doc2.pdf",
  created_at: Wed, 20 Jan 2016 04:32:22 UTC +00:00,
  updated_at: Wed, 20 Jan 2016 04:32:22 UTC +00:00,
  user_id: 2>,
#<Document:0x007f2d28431550 id: nil, name: nil, created_at: nil, updated_at: nil, user_id: 2> ]

但我们仍有@documents.count = 2

在这里,count是相同的。但该集合包含另一个对象。 我怎么能理解rails的这种行为。另外我如何冻结@documents来获取文档集合。

2 个答案:

答案 0 :(得分:1)

@documents = @user.documents添加了对@user.documents数组的引用。 @user.documents.build使该数组发生变异,因此@documents将始终显示新记录。

您有两种方法可以解决此问题:

@document初始化为Document并手动设置外键,而不是通过@documents。这不会将新记录添加到@user.documents

@documents = @user.documents
@document = Document.new(user: @user)

使用documents制作#dup数组的副本,而不是引用它。

@documents = @user.documents.dup
@document = @user.documents.build

答案 1 :(得分:0)

@documents指向@user的文档。您应该在document而不是@user上构建新的@member,以查看@documents集合中新构建的文档。

按以下步骤更新edit操作,应显示@user的三个文档以及@document上新建的文档:

class MembersController < ApplicationController
   def edit
    @user = User.find(params[:id])
    @documents = @user.documents   # List document
    @document =  @documents.build   # Build document on `@user`.
  end
end