Holding an ActiveRecord object for later use.

This is probably a noob question..

I have a fairly large query (the result takes along time to return) that I need to export to CSV after it is displayed with a view. Basically a link at the bottom of the page, "Export to CSV". I've found the rails wiki solution: Peak Obsession . The only problem is that I would like to have this in it's own controller and I'm wondering how I should keep a handle on the ActiveRecord object that has already been created from the query, I would also like to keep this as DRY as possible and not have to regenerate the query. Should I store the ActiveRecord object in the session variable or ???

Thanks for any help or advice, -dustin

Storing AR objects in the session will work, but there is no guarentee that the data will persist. The only thing you can count on with AR objects is the object ID (primary key, whatever it is). In this case, that if you run the query, save the AR object to the session, and then access elsewhere, given a large enough dataset, ActiveRecord will most likely have forgotten the results and will rerun the query when you access it again.

In this case, just pass the object id to the CSV controller. That way you know the query will only be generated and run once.


I wasn't aware that AR cached result data?

My suggestion would be to write the csv file to disk, preferably with something like Zlib to compress it also, then use send_data/send_file depending on the size to send the file to the browser. On subsequent requests only generate the csv file if the data has changed.

Since this is a large query I don't think I'd store it in the session. What happens if the user doesn't want to download the csv? Then you've stored it for no reason. If it's somewhat static data you could cache both the rhtml view and also a csv version. Then have those expire when the data is updated.

A simpler solution would be to just paginate the results for the user, and then do the full query for csv creation. Caching could work in this scenario as well, but it all depends on your needs. If pagination is out of the question, and so is caching, then create the csv file just prior to rendering the view. This way you won't have to generate it twice at least.

Cheers, John