Rails 3和update_attribute上的奇怪关系行为

我很难找到测试失败的原因:

describe User, "Instance Methods" do describe "leave_group!" do it "should set group_id to nil" do @user = Factory(:user) @group_2 = Factory(:group, :owner => @user) @user.leave_group! @user.reload.group_id.should be_nil # THIS LINE IS FAILING!!! end it "should assign another owner to group, if owner was user" do @user = Factory(:user) @group = Factory(:group, :owner => @user) 1.upto(4) { @group.add_user Factory(:user) } @user.leave_group! @group.reload.owner.should_not eql(@user) end end end 

这些是我正在使用的模型:

 class User  "Group", :foreign_key => "owner_id" belongs_to :group def leave_group! current_group_id, current_group_owner = self.group.id, self.group.owner self.group_id = nil save! Group.find(current_group_id).randomize_owner! if current_group_owner == self end end class Group  1 begin new_user = current_users.sort_by { rand }.first end while self.owner == new_user self.owner_id = new_user.id save! end end 

我在这里做错了吗? 我能改进吗? 更重要的是,为什么单一测试失败了?

这是运行该单个测试的日志输出:

 SQL (0.2ms) SELECT name FROM sqlite_master WHERE type = 'table' AND NOT name = 'sqlite_sequence' AREL (0.3ms) INSERT INTO "users" ("name", "uid", "provider", "email", "image_url", "group_id", "created_at", "updated_at", "timezone", "public_readings", "is_visible_on_leaderboards", "phone_number") VALUES ('John Doe', '314159265', 'facebook', 'john@does.com', NULL, NULL, '2011-07-18 02:02:08.455229', '2011-07-18 02:02:08.455229', NULL, 't', 't', NULL) Group Load (0.1ms) SELECT "groups".* FROM "groups" WHERE "groups"."key" = 'SNYEMJ' LIMIT 1 AREL (0.1ms) INSERT INTO "groups" ("name", "key", "score", "owner_id", "created_at", "updated_at") VALUES ('John''s Group', 'SNYEMJ', 0, 1, '2011-07-18 02:02:08.522442', '2011-07-18 02:02:08.522442') AREL (0.0ms) UPDATE "users" SET "group_id" = 1, "updated_at" = '2011-07-18 02:02:08.524342' WHERE "users"."id" = 1 Group Load (0.1ms) SELECT "groups".* FROM "groups" WHERE "groups"."id" = 1 LIMIT 1 User Load (0.2ms) SELECT "users".* FROM "users" WHERE ("users".group_id = 1) User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1 

最后3行都是选择,通知栏甚至没有尝试从用户中删除group_id。 (有2个插入,1个用于测试用户,1个用于测试组,1个更新用于将group_id分配给测试用户)。

尝试在测试中的@user.reload之前添加@user.reload调用。

即使从工厂创建@group_2时用户记录在数据库中更新了它的组,我怀疑@user对象不是。 然后你打电话给leave_group! 使用group ID为nil的@user ,因此保存将不会执行任何操作,因为对象未更改。 然后在测试的下一行中重新加载@user ,它现在具有之前分配的DB中的group_id

尝试使模型类如下:

 class User < ActiveRecord::Base # Associations has_one :own_group, :class_name => "Group", :foreign_key => "owner_id" belongs_to :group def leave_group! group_randomize_owner self.group.clear end private def group_randomize_owner if group.owner == self group.randomize_owner! end end end