如何知道何时在 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"

我花了一个小时调试这个:)。在我的初始版本中,我没有在確 _ email _ user _ url 被访问后重新初始化 user,而且即使用户被激活,状态始终是 inactive

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

52914 次浏览

You'd need to call user.reload whenever the data has changed in the database.

In your above code, the "user" object is created in memory from the data fetched from the database by User.first. Then, it looks like your confirm_email_user_url modifies the database. The object doesn't know about this until you reload it, which re-acquires the data from the database.

I'm not sure if there's a programmatic way to know when you will need to reload the object, but as a developer you should be aware of what is going on and handle appropriately. In most of my experience (which is somewhat limited), this is only an issue during testing. In production, it's not typical for an object to be modified in the database while it is loaded in memory. What usually happens is the object in memory is modified and then saved to the database (i.e., user.email = "foo@bar.com" followed by user.save). I suppose if you had a high-activity application where lots of users might be modifying something in short succession, you would want to be careful about it.

Btw. this doesn't really work when you do stuff on the model itself like Report.count. After endless tries of resetting the column information or getting an instance of the first/last record and reload it the only thing that helped me was reconnecting the database between the counts like this:

initial_count = Report.count


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


Report.connection.reconnect!
final_count = Report.count

This worked for Rails 2.3.8+, I don't know about the 3+ versions.