Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I know when to "refresh" my model object in Rails?

Here's part of an integration test that I'm having:

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" 

I spent the last hour debugging this :). In my initial version, I wasn't reinitializing user after confirm_email_user_url was accessed, and the state was always inactive even though the user was activated.

How do I know if I should "reload" ( lacking of a better name ) my model object? What should I call in order to do so?

like image 477
Geo Avatar asked Apr 01 '11 22:04

Geo


People also ask

What does reload do in Rails?

Reloads the attributes of object(here @user) from the database. It always ensures object has latest data that is currently stored in database.

What is call back in Ruby?

Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.

What is the difference between new and create in rails?

New instantiates a new Model instance, but it is not saved until the save method is called. Create does the same as new, but also saves it to the database. Sometimes you want to do stuff before saving something to the database, sometimes you just want to create and save it straight away.

What are Ruby on Rails models?

A Rails Model is a Ruby class that can add database records (think of whole rows in an Excel table), find particular data you're looking for, update that data, or remove data.


2 Answers

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 = "[email protected]" 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.

like image 105
dantswain Avatar answered Sep 21 '22 13:09

dantswain


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.

like image 20
Thomas Fankhauser Avatar answered Sep 22 '22 13:09

Thomas Fankhauser