Ruby on rails 重新分配id为零的用户

Ruby on rails 重新分配id为零的用户,ruby-on-rails,ruby,rspec,factory-bot,Ruby On Rails,Ruby,Rspec,Factory Bot,今天我遇到了一个令人惊讶的Rails/Rspec/FactoryGirl(?)怪癖。我已经找到了一个解决方案,但我感兴趣的是问题为什么会首先发生 我的例子是: let(:old_user) { build(:user) } let(:new_user) { create(:user) } let(:post) { build(:post, user: old_user) } it 'sets the new user' do post.user_id = new_user.id pos

今天我遇到了一个令人惊讶的Rails/Rspec/FactoryGirl(?)怪癖。我已经找到了一个解决方案,但我感兴趣的是问题为什么会首先发生

我的例子是:

let(:old_user) { build(:user) }
let(:new_user) { create(:user) }
let(:post) { build(:post, user: old_user) }

it 'sets the new user' do
  post.user_id = new_user.id
  post.save
  post.reload
  post.user.should == new_user
end
这个测试失败了。测试结束时,用户分配不正确。用户仍然是老用户。(这也是一个完全无用的测试。)

有几种方法可以让考试通过。一种方法是
创建
旧用户
,以便在尝试重新分配前设置
post.user\u id
。另一种方法是将
post.user\u id=new\u user.id
替换为
post.user=user.find(new\u user.id)
。但我很好奇

当测试失败时,原始代码在幕后发生了什么

编辑:按要求添加工厂

FactoryGirl.define do
  factory :user do
    # We actually use Faker, but for this purpose I gave strings
    name 'Test User'
    email 'example@example.com'
    password 'changeme'
    password_confirmation 'changeme'
  end
end

# The Post class has `belongs_to :user`
FactoryGirl.define do
  factory :post do
    body 'I am a post'
  end
end

你能把你的工厂包括在
build(:user)
build(:post)
中吗?哇,太酷了!我能够重现这个问题。解决此问题的另一种方法是在用户id的分配和保存之间插入“post.user”。在帖子和老用户之间似乎存在“待定关联”。明确地为外键指定值不会中断挂起的关联,因此,在执行post.save时,会保存旧的用户记录,并将id分配给fk。通过在post.save之前执行“post.user”,我们可以重新加载关联的用户,从而取消挂起的关联。@tyler-done,它们非常标准。@SteveTurczyn-哦,有趣的是,我没有找到那个修复方法。是的,这一定是与“待定协会”有关,但我不明白它是如何运作的。一些黑魔法…我的概念模型是。。。内存中有这些对象到对象的关联,这些关联在将对象持久化到数据库时被转换为fk写入。但在保存之前,rails关联仍然是对象对对象的。仅仅因为您尝试为fk插入一个新值并不意味着关联消失。当我打开帖子时,我可以看到fk像预期的那样变为“1”,然后在保存后立即变为“2”,所以它显然不在乎你在fk里放了什么东西。无论如何,好问题!