On Tue, Jul 19, 2005 at 07:29:59PM +0200, Joost Diepenmaat
wrote:> Hi all,
>
> Is there any way to specify that certain columns in an activerecord
> object should be lazy-loaded ( grabbed from the DB only when their value
> is requested )?
>
> The only way I see in the docs is to put those columns in a seperate
> table, but I''d rather not do that.
Well... I did it anyway, since it appears to be the simplest way of
achieving this. This is what I did:
I''m storing images in the database (yes, I know there are disadvantages
to that - I''m planning on caching the resulting images in a proxy,
anyway
the same situation applies when you''ve get - say - a Page class with a
potentially large text field that you don''t need when you''re
building a
navigation tree).
So I have a table "images" and a model "Image".
Because I don''t want to have to retrieve the binary data every time I
want
to generate an img tag in HTML, I put the data field in a seperate
table "image_blobs" and generated the model ImageBlob. Then I added
the
following to Image:
class Image
# ...
has_one :image_blob # refered via the image_blob_id field
def data
if image_blob_id and image_blob_id > 0
return ImageBlob.find(image_blob_id).data
end
nil
end
def data=(data)
if self[:image_blob_id] and self[:image_blob_id] > 0
return ImageBlob.update image_blob_id, { :data => data }
else
blob = ImageBlob.new
blob.data = data
blob.save
self[:image_blob_id] = blob.id
self.save
end
end
# ...
end
Which means that as far as the rest of the model is concerned, they
can mostly use the Image class as if "data" is part of Image. There
are
still a few issues:
* AFAIK Image.new( fields ) and Image.attributes etc don''t accept the
data field - that''s OK for this particular application, but it does
mean you can''t rely on the create/update routines from the scaffolding.
* If you have large images, reading the whole data field in memory is
inefficient anyway. I''m planning on converting the image displaying to
use the ActionController::Streaming code, but I can''t see an equivalent
method for *uploading* large fields to the database.
* By the way, I would still like built-in lazy population of fields,
something like how the perl libary Class::DBI does it:
http://search.cpan.org/dist/Class-DBI/lib/Class/DBI.pm#LAZY_POPULATION
Any tips will be appreciated.
Cheers,
Joost.