我怎么知道何时在Rails中“刷新”我的模型对象?


68

这是我正在进行的集成测试的一部分:

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"

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

我如何知道是否应该“重新加载”(缺少更好的名称)我的模型对象?我应该怎么称呼呢?


3
确实,重载是适当的术语,您可以使用user.reload
apneadiving 2011年

Answers:


134

user.reload每当数据库中的数据更改时,您都需要调用。

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

我不确定是否有编程方式可以知道何时需要重新加载该对象,但是作为开发人员,您应该知道发生了什么并适当地进行了处理。根据我的大部分经验(有所限制),这只是测试期间的一个问题。在生产中,将对象装载到内存中时通常不会在数据库中对其进行修改。通常会发生的事情是修改内存中的对象,然后将其保存到数据库中(即,user.email = "foo@bar.com"随后是user.save)。我想如果您有一个高活动性的应用程序,其中许多用户可能会在短期内修改某些内容,那么您需要对此加以注意。


我不明白,user = User.first不会User.first再次触发查询吗?它应该自动重新加载?没有?
山姆YC

User.first将再次查询数据库。您可以通过rails c在一个窗口中打开另一个窗口来检查它tail -f log/development.rb。然后在控制台中键入user = User.first两次。您将在第二个带有日志的窗口中看到两个查询
ToTenMilan

6

顺便说一句。当您在模型本身上做诸如此类的事情时,这实际上是行不通的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+版本。


对于我的特定用例(多个请求访问同一数据,然后一个请求更新数据,第二个请求尝试获取更新),等效于user.reload无效,但是Report.connection.reconnect!工作了。
SWoo,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.