In my current rails app I'm pulling a lot of data from the database into memory so that I can start a long-running background task that I don't want to hit the database every 5 seconds.
This is all working great but I have some inelegant code that I'd like to get rid of if possible.
For an example, I have the situation where I have a User model and that User model can link to other User models in the form of Contacts, which in turn can link back to the first User model an so on. This is modelled as follows (thanks to Milan Novota for his earlier help): -
class User < ActiveRecord::Base
has_many :contact_records, :foreign_key => :owner_id
has_many :contacts, :through => :contact_records, :class_name => "User"
end
class ContactRecord < ActiveRecord::Base
belongs_to :owner, :class_name => "User"
belongs_to :user
end
So now I can type
user_a_contacts = user_a.contact_records
=> [user_b, user_c]
and get all the contacts for user a. Now let's say I want to get user b's contacts via user a's (can't think why I would but it's only an example!)
user_b_contacts = user_a_contacts.first.contact_records
=> [user_a, user_c]
Now I can get user a's name (in a convoluted, roundabout, never-use-in-the-real-world kind of way)
user_a_name = user_b_contacts.first.name
=> "Jamie"
So far, so good. Now I change user a's name
user_a.name = "Sandy"
=> "Sandy"
If accessing user a's name again as before from the database I get
user_a_name = user_b_contacts.first.name
=> "Sandy"
However, if I've eager loaded and kept this value in memory I get
user_a_name = user_b_contacts.first.name
=> "Jamie"
but doing the following gives me the right answer
user_a.name
=> "Sandy"
Fairly obviously, the eager-loading is creating different User objects for the original users and those eager-loaded from the ContactRecord objects.
So (finally!) my question is this: -
At the moment, I have bodged around this by using
@users.each.detect{|user| user == user_b_contacts.first}
(where @users is the eager-loaded list of User objects). Is there a way that I can update the eager-loaded User objects instead?
Please note: -
a) I am eager-loading using the following
User.find(:all, :include => [ {:contact_records => :contacts] } ])
b) Obviously this is not the actual code that I am working with but there would have been even more explanation and exposition in order to show that code and I think I've bored you enough! Trust me that the real example I am using DOES require this structure in order to work correctly, as bizarre as it might look! ;)
c) I may have introduced typos and errors when reconstructing the example but please ignore those. All I need to know is whether it is possible to reload the eager-loded Users without hitting the database.
Many thanks in advance!
UPDATE: As mentioned below, the model data will not be saved to the database until the very end of the process run so reloading will not work as the data in the database won't have changed.