Rails 测试函数中的数据库记录不是 saving/persisting?

Database Record not saving/persisting within a Rails test function?

我有一个 update 类型的方法,我正在尝试使用 MiniTest 和 FactoryGirl 在 Rails 中进行测试。我的问题是,虽然我可以看到更新 正确发生 更新函数中,但它似乎没有返回到测试功能正常。

这些是我们正在使用的对象,(obj 被赋予默认值 location 以开始:

location1 = create :location
location2 = create :location
obj = create :object, location: location1

然后我们调用 update 函数,它需要 id 的:

obj.update_location(obj.id, location2.id)

update函数:

def update_location(obj_id, loc_id)
    @obj = Object.find(obj_id)
    @obj.location_id = loc_id
    @obj.save
end

但是当回到测试文件时,我尝试 assert 更改…

assert_equal obj.location_id, location2.id

...我失败了。控制台告诉我 obj.location_id 仍然等于 location1.id!这是为什么?

似乎 @obj.save 正常工作,因为我在更新函数中插入 puts @obj.inspect 并且它输出正确更新的 location_id.

我认为这与事务回滚无关,因为这一切都发生在单个测试中。 (我的印象是事务回滚只发生在测试之间)。

总而言之,我的问题是:为什么我的更新没有持续回到 rails MiniTest test 函数?

编辑:这是整个测试:

test "update_location" do    
    location1 = create :location
    location2 = create :location

    #give the obj a starting `type`
    obj = create :obj, location: location1

    obj.update_location(obj.id, location2.id)   
    assert_equal obj.location_id, location2.id    
end

2 个可能会帮助您找到答案的问题:

  1. 为什么要使用实例变量 @obj 而不是局部变量 obj

  2. 为什么你有一个特殊的方法只更新1列。 update_column 对你不起作用吗?

问题已解决,以下是我的理解:

问题在于 rails' ORM 的工作方式。原始对象 'obj' 在创建时加载了数据库中的数据……但以后对数据库的更改不会自动存储到 obj。我原以为 obj.some_attribute 查看数据库中的记录 obj 以找到属性值——但实际上我认为属性只是在变量创建时加载到变量中,并且数据库如果我稍后调用 obj.some_attribute,则无法访问。

通常,当通过变量本身完成更新时,Rails 知道为您更新变量。所以当你写 obj.some_attribute = 5,然后再写 obj.some_attribute 时,Rails 知道值应该是 5。但是 Rails 魔法在这种情况下不会发生因为它没有通过变量更新记录。

所以需要做的只是reload数据库中的对象。

所以 assert_equal obj.reload.location_id, location2.id 有效!