2011-04-01 67 views
55

下面是我有一个集成测试的一部分:如何知道何时在Rails中“刷新”我的模型对象?

user = User.first 
assert !user.is_active? 

get confirm_email_user_url(user),:confirmId => user.mail_confirmation_hash 

assert_equal response.status,200 
# because confirm_email_user_url modifies the activation state of the object 
user = User.first 
assert_equal user.state,"activated" 

我度过的最后一个小时的调试这个:)。在我的初始版本中,在confirm_email_user_url被访问后,我没有重新初始化user,并且即使用户被激活,状态也始终为inactive

如何知道我是否应该“重新加载”(缺少更好的名称)模型对象?我应该怎么打电话才能这样做?

+2

确实,重新加载是合适的术语,你可以使用user.reload – apneadiving 2011-04-01 23:13:22

+1

可能是有用的:http://www.alexanderinteractive.com/blog/2009/02/tip-reloading-activerecord-instances/ – apneadiving 2011-04-01 23:19:11

回答

111

只要数据库中的数据发生变化,您就需要致电user.reload

在上面的代码中,“用户”对象是通过User.first从数据库中获取的数据在内存中创建的。然后,看起来您的confirm_email_user_url修改了数据库。直到你从reload中重新获取数据库中的数据,该对象才知道这个。

我不确定是否有程序化的方式来知道什么时候需要重新加载对象,但作为开发人员,您应该知道正在发生的事情并正确处理。在我的大部分经验中(这是有限的),这只是测试过程中的一个问题。在生产中,在数据库加载到内存中时,数据库中的对象不会被修改。通常发生的情况是修改内存中的对象,然后将其保存到数据库(即,user.email = "[email protected]"后跟user.save)。我想如果你有一个高活动的应用程序,很多用户可能会在短时间内连续修改某些内容,那么你应该小心一点。

+0

我不'不明白,'user = User.first','User.first'不会再次触发查询?它应该自动重新加载?没有? – GMsoF 2016-12-15 08:18:09

5

Btw。当你在模型上做东西时,这不起作用,如Report.count。之后重置列信息或获得第一个/最后一个记录的实例,并重新加载它帮助我在重新连接计数之间的数据库这样的唯一的无尽尝试:

initial_count = Report.count 

# do something, like invoking a rake task that imports the reports, .. 

Report.connection.reconnect! 
final_count = Report.count 

这个工作对Rails的2.3。 8+,我不知道3 +版本。

+0

对于我的特殊用例(多个请求访问相同的数据,然后一个请求更新数据,第二个请求尝试获取更新),相当于user.reload无效,但Report.connection.reconnect!工作。 – SWoo 2015-06-25 02:43:57

相关问题