为什么我的规范生成的记录没有有效的 ID 值?

Why don't my records that my specs generate have valid ID values?

这是我初始化实例变量的方式:

context "when the inviter is being deleted and invited HAS accepted invitation" do
  before :each do
    @user1 = create(:user, gender: 0)
    @user2 = create(:user)
    @membership1 = create(:membership, member: nil, family_tree: @user1.family_tree, inviter: @user1, invited: @user2, relation: "sister", relative_type: 1)
    @membership2 = create(:membership, member: nil, family_tree: @user2.family_tree, inviter: @user2, invited: @user1, relation: "brother", relative_type: 1)
    @connection = create(:connection, inviter_membership: @membership1, invited_membership: @membership2, inviter_user: @user1, invited_user: @user2, request_status: 1)
    sign_in @user1
  end

然而,当我 运行 这个测试时:

  it "should NOT delete the inviter_membership record" do
    inviter_membership = @membership1
    delete :destroy, id: @user1
    expect(Membership.find(inviter_membership.id)).to be inviter_membership        
  end

我收到这个错误:

ActiveRecord::RecordNotFound: Couldn't find Membership with 'id'=1441

当我在 PRY 控制台探索我的数据库时,由于这次测试失败而生成的,这些是我的结果:

[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> inviter_membership
=> #<Membership id: nil, family_tree_id: 31704, user_id: 13101, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", relation: "sister", member_id: nil, invited_id: 13102, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 31704, user_id: 13101, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", relation: "sister", member_id: nil, invited_id: 13102, relative_type: 1>

不是初始 membership.id: nil 值。当我检查我的其他记录时,我看到了类似的东西:

[5] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user1
=> #<User id: nil, email: "eleanore.keeling@lindgrenhettinger.net", encrypted_password: "a$lROCfnS8rHf3Y2CKp0Ozw.9zsqa4rXTmxU6QvpGUm9S...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", first_name: "Murphy", confirmation_token: nil, confirmed_at: "2016-01-28 20:46:56", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "a", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Facere consequatur odio recusandae aut ipsa repudi...", last_name: "Haag", gender: 0, birthday: nil>
[6] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user2
=> #<User id: nil, email: "dillon.feest@jacobson.biz", encrypted_password: "a$ju0c8gr/RUaPeRNneh5rVOAN3QtUoMEzy9UwM4.a.D3...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", first_name: "Neva", confirmation_token: nil, confirmed_at: "2016-01-28 20:46:56", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "voluptatem", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Reiciendis optio mollitia et vel. Adipisci odit el...", last_name: "Rippin", gender: 1, birthday: nil>
[7] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: nil, family_tree_id: 31706, user_id: 13102, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", relation: "brother", member_id: nil, invited_id: 13101, relative_type: 1>

不确定它是否与保存有关,但奇怪的是我的 @connection 值实际上有一个有效的 id:

[4] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @connection
=> #<Connection id: 1892, membership_id: 1441, sent_at: "2016-01-23 01:58:47", responded_at: "2016-02-12 11:17:20", send_limit: 5, times_sent: 1, removed_at: "2016-01-28 20:46:58", created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", request_status: 1, invited_membership_id: 1442, invited_user_id: 13102, inviter_user_id: 13101>

我唯一能想到的是,在我的代码中,我实际上在这个 @connection 的等价物上调用了 connection.update(...)。那么也许那个电话保存了记录?

如果是这样,我如何将我的记录保存在 Rspec 中(我想保存吗??)或者我如何在数据库中找到该记录?我需要确认它没有被删除

编辑 1

如果我在 @membership1 初始化中使用 build 而不是 create 并深入研究,这就是我得到的:

[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 31799, user_id: 13146, created_at: "2016-01-28 21:08:09", updated_at: "2016-01-28 21:08:09", relation: "sister", member_id: nil, invited_id: 13147, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> inviter_membership
=> #<Membership id: nil, family_tree_id: 31799, user_id: 13146, created_at: "2016-01-28 21:08:09", updated_at: "2016-01-28 21:08:09", relation: "sister", member_id: nil, invited_id: 13147, relative_type: 1>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1.valid?
=> true
[5] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1.errors
=> #<ActiveModel::Errors:0x007fbd2f9fb458
 @base=
  #<Membership id: nil, family_tree_id: 31799, user_id: 13146, created_at: "2016-01-28 21:08:09", updated_at: "2016-01-28 21:08:09", relation: "sister", member_id: nil, invited_id: 13147, relative_type: 1>,
 @messages={}>

编辑 2

所以这是奇怪的事情,我在顶部的 before :each 中放了一个 binding.pry 来检查在将执行发送到每个 it 块之前生成的值.这些值确实有 ID。

  51:         @membership1 = build(:membership, member: nil, family_tree: @user1.family_tree, inviter: @user1, invited: @user2, relation: "sister", relative_type: 1)
    52:         @membership2 = create(:membership, member: nil, family_tree: @user2.family_tree, inviter: @user2, invited: @user1, relation: "brother", relative_type: 1)
    53:         @membership3 = build_stubbed(:membership)
    54:         @connection = create(:connection, inviter_membership: @membership1, invited_membership: @membership2, inviter_user: @user1, invited_user: @user2, request_status: 1)
    55:         sign_in @user1
 => 56:         binding.pry
    57:       end
    58: 
    59:       it "should confirm that inviter_membership has nil member_id" do
    60:         expect(@user1.inviter_memberships.first.member).to be nil
    61:       end

[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: 1474, family_tree_id: 31878, user_id: 13183, created_at: "2016-01-28 21:37:38", updated_at: "2016-01-28 21:37:38", relation: "sister", member_id: nil, invited_id: 13184, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: 1473, family_tree_id: 31880, user_id: 13184, created_at: "2016-01-28 21:37:38", updated_at: "2016-01-28 21:37:38", relation: "brother", member_id: nil, invited_id: 13183, relative_type: 1>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership3
=> #<Membership id: 1007, family_tree_id: 1001, user_id: 1003, created_at: nil, updated_at: nil, relation: "possimus", member_id: 1006, invited_id: 1005, relative_type: 0>

但是,在我关心的 it 块中,它似乎覆盖了每个实例变量的 id 值,除了我刚刚用 build_stubbed 方法添加的那个比 create:

    71:         inviter_membership = @membership1
    72:         delete :destroy, id: @user1
 => 73:         expect(Membership.find(inviter_membership.id)).to be inviter_membership
    74:       end
    75: 
    76:       it "should create a member record with inviter_user's info" do
    77:         expect {
    78:           delete :destroy, id: @user1

ActiveRecord::RecordNotFound: Couldn't find Membership with 'id'=1478
from /gems/activerecord-.1.14/lib/active_record/relation/finder_methods.rb:320:in `raise_record_not_found_exception!'
[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 31886, user_id: 13187, created_at: "2016-01-28 21:38:23", updated_at: "2016-01-28 21:38:23", relation: "sister", member_id: nil, invited_id: 13188, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: nil, family_tree_id: 31888, user_id: 13188, created_at: "2016-01-28 21:38:23", updated_at: "2016-01-28 21:38:23", relation: "brother", member_id: nil, invited_id: 13187, relative_type: 1>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership3
=> #<Membership id: 1021, family_tree_id: 1015, user_id: 1017, created_at: nil, updated_at: nil, relation: "at", member_id: 1020, invited_id: 1019, relative_type: 0>

什么可以覆盖 it 块中的 id 值?

编辑 3

所以身份验证发生了一些奇怪的事情。

如果我这样做 sign_in @user2,那么失败的测试现在通过了。

这是失败的测试 sign_in @user1,但通过 sign_in @user2:

  it "should NOT delete the inviter_membership record" do
    expect {
      delete :destroy, id: @user1
    }.not_to change(Membership,:count)
  end

我尝试完全注释掉 sign_in 行,这也导致上述测试通过。

奇怪的是,在我的 user 模型上,我有一个 before_destroy :callback,当我在该方法中放置一个 binding.pry 时,它不会在该测试中执行,因为失败和通过的测试。所以好像回调没有被调用,超级奇怪。

我不是 100% 确定这是否是答案和正确的解释,但 Rspec 向我抛出的错误终于得到修复。

我相信正在发生的事情是在 before :each 它成功地创建了对象并将其保存到数据库中。但是,当规范失败时......它基本上 'builds' 对象并向我显示规范失败后重建的对象。所以这就是为什么我没有看到 object.id

我相信是这样,因为如果我在每个单元测试中放置一个常规的 binding.pry 不会失败,然后我查询在 before :each 中初始化的实例变量,它看起来很正常。例如:

  it "should NOT delete the inviter_membership record" do
    sign_in @user2
    binding.pry
    expect {
      delete :destroy, id: @user1
    }.not_to change(Membership,:count)
  end

结果:

[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user1
=> #<User id: 13667, email: "cale@stehr.name", encrypted_password: "a$h.2yrLwRb1J1uJoWtFKUOuG.IW.UnchqXbfC7v.bJic...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-30 22:27:12", updated_at: "2016-01-30 22:27:12", first_name: "Daisy", confirmation_token: nil, confirmed_at: "2016-01-30 22:27:10", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "vel", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Maxime vitae dolorem atque perferendis sed fuga. A...", last_name: "Rohan", gender: 0, birthday: nil>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user2
=> #<User id: 13668, email: "ashley_lockman@carroll.net", encrypted_password: "a$x3XvAGUAaxE0Kk8mtgcFCOb7FrGnPc3IS0wET/xauQU...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-30 22:27:12", updated_at: "2016-01-30 22:27:12", first_name: "Elliott", confirmation_token: nil, confirmed_at: "2016-01-30 22:27:10", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "ducimus", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Aperiam ut quia ea inventore non ad. Nobis nisi di...", last_name: "Hickle", gender: 1, birthday: nil>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: 1747, family_tree_id: 32888, user_id: 13667, created_at: "2016-01-30 22:27:12", updated_at: "2016-01-30 22:27:12", relation: "sister", member_id: nil, invited_id: 13668, relative_type: 1>
[4] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: 1748, family_tree_id: 32890, user_id: 13668, created_at: "2016-01-30 22:27:12", updated_at: "2016-01-30 22:27:12", relation: "brother", member_id: nil, invited_id: 13667, relative_type: 1>
[5] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @connection
=> #<Connection id: 2351, membership_id: 1747, sent_at: "2016-01-25 01:35:36", responded_at: "2016-02-07 13:16:04", send_limit: 5, times_sent: 1, removed_at: "2016-01-30 22:27:12", created_at: "2016-01-30 22:27:12", updated_at: "2016-01-30 22:27:12", request_status: 1, invited_membership_id: 1748, invited_user_id: 13668, inviter_user_id: 13667>

只有当规范失败时,它才会向我显示非持久对象,如下所示:

RSpec::Expectations::ExpectationNotMetError: expected #count to have changed, but is still 2
from /gems/rspec-expectations-3.2.1/lib/rspec/expectations/fail_with.rb:29:in `fail_with'
[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user1
=> #<User id: nil, email: "maurine.abbott@heaney.name", encrypted_password: "aAJpP7/UwUDoYMw/YrSd2O2qy.nSZguZGnlWyNt8mVV...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-30 22:28:22", updated_at: "2016-01-30 22:28:22", first_name: "Ashtyn", confirmation_token: nil, confirmed_at: "2016-01-30 22:28:20", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "doloribus", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Perspiciatis dolor natus ut incidunt aperiam culpa...", last_name: "Jones", gender: 0, birthday: nil>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user2
=> #<User id: nil, email: "scotty.dooley@metz.name", encrypted_password: "a$ReYuDORNmKSNeDEYPZrmwuFHPfkv2JWypPQjmKuQVuy...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-30 22:28:22", updated_at: "2016-01-30 22:28:22", first_name: "Albin", confirmation_token: nil, confirmed_at: "2016-01-30 22:28:20", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "dolores", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Rerum soluta dolorum harum rerum fuga repudiandae....", last_name: "Dooley", gender: 1, birthday: nil>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 32975, user_id: 13708, created_at: "2016-01-30 22:28:22", updated_at: "2016-01-30 22:28:22", relation: "sister", member_id: nil, invited_id: 13709, relative_type: 1>
[4] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: nil, family_tree_id: 32977, user_id: 13709, created_at: "2016-01-30 22:28:22", updated_at: "2016-01-30 22:28:22", relation: "brother", member_id: nil, invited_id: 13708, relative_type: 1>
[5] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @connection
=> #<Connection id: 2375, membership_id: 1763, sent_at: "2016-01-25 00:35:20", responded_at: "2016-02-20 13:06:58", send_limit: 5, times_sent: 1, removed_at: "2016-01-30 22:28:22", created_at: "2016-01-30 22:28:22", updated_at: "2016-01-30 22:28:22", request_status: 1, invited_membership_id: 1764, invited_user_id: 13709, inviter_user_id: 13708>

我仍然不明白为什么最后一个实例变量 - @connection - 被正确保留而其他的不是......唉......它现在对我来说工作正常。

我希望这对某人有所帮助!