Imagine that I have a class Book, and a class Chapter, and Chapter has a
text attribute that contains the text of the chapter. Is there a
convenient railsy way to tell Chapter to only load chapter.text from the
db when/if it’s specifically called for? For instance, if I’m using @book.chapters to build a TOC, I’m not the least bit interested in the
chapter.text for all those chapters at this point, and am worried that
loading all that extra data will slow down the app. I’m wondering if I
can say something like…
class Chapter < ActiveRecord::Base
lazy_load :text
or maybe…
class Book < ActiveRecord::Base
has_many :chapters, :lazy_load => [ :text ]
But so far the only option I can think of is to offload the text to it’s
own model ChapterText that belongs_to :chapter. I’ve been digging
through the API off and on for a couple weeks now hoping to stumble on
an elegant solution, but haven’t yet. So, I’m thinking it’s not
currently possible, except for using an extra model. Ideas?
an elegant solution, but haven’t yet. So, I’m thinking it’s not
currently possible, except for using an extra model. Ideas?
I think the :select option for a find allows you to specify which
columns to return. Something like…
Chapter.find(:all, :select=>‘id, title’) will return Chapter objects
with only the ‘id’ and ‘title’ populated.
Seems like it wouldn’t be too difficult to setup a class method that
returns the names of all the columns without the ones you want to lazy
load. You could then override the find method to automatically
populate the ‘select’ option with these values.
The problem there though, is that if you later try to access that data
you didn’t load, ActiveRecord raises a “NoMethodError”, rather than
going back to the database to get the data. I suppose if used very
carefully though, that could be a viable option.
The problem there though, is that if you later try to access that data
you didn’t load, ActiveRecord raises a “NoMethodError”, rather than
going back to the database to get the data. I suppose if used very
carefully though, that could be a viable option.
You might be able to use ‘method_missing’ to load the ‘missing’ data
when you need it.
_Kevin
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.