Rails 3和update_attribute上的奇怪关系行为 [英] Weird relationship behavior on Rails 3 and update_attribute

查看:90
本文介绍了Rails 3和update_attribute上的奇怪关系行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a hard time trying to find out why a test is failing:

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

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

These are the models I'm using:

class User < ActiveRecord::Base
  # Associations
  has_one :own_group, :class_name => "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 < ActiveRecord::Base
  # Associations
  has_many :users
  belongs_to :owner, class_name: "User"

  def randomize_owner!
    current_users = self.users
    return false unless current_users.length > 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

我在这里做错什么了吗?我可以改善吗?更重要的是,为什么单个测试失败?

Am I doing something wrong here? Could I improve it? And more importantly, why is that single test failing?

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

Here's the log output for runing that single test:

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行全都是选择,注意rails甚至没有尝试从用户中删除group_id. (有2个插入,其中1个用于测试用户,1个用于测试组,以及1个将group_id分配给测试用户的更新.)

The last 3 lines are all selects, notice rails doesn't even try to remove the group_id from the user. (There are 2 inserts, 1 for the test user and 1 for the test group and 1 update which assigns group_id to the test user).

推荐答案

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

Try adding a @user.reload call before @user.leave_group in the test.

即使从工厂创建@group_2时,用户记录在数据库中已更新为数据库中的组,但我怀疑@user对象不是.然后用@usergroup ID为nil调用leave_group!,因此保存不会执行任何操作,因为对象未更改.然后,在测试的下一行中,重新加载@user,现在已从先前分配的数据库中添加了group_id.

Even though the user record is updated with it's group in the DB when you create @group_2 from the factory, I suspect the @user object is not. Then you call leave_group! with a @user with a group ID of nil, so the save won't do anything because the object is unchanged. Then in the next line of your test you reload the @user, which now has the group_id from the DB assigned earlier.

这篇关于Rails 3和update_attribute上的奇怪关系行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆