Hi,
Is there a concept of having a model attribute loaded only when
necessary. For example, I have a model called product with an
attribute called file which is stored in the database as a blob. I
would like to be able to retrieve a bunch of products as an array
without having to load the file BLOB. Only loading it when necessary.
Not sure if my suggestion is the best since it’s not 100% automatic, but
almost
You could use the :select clause of find, so you select only those
attributes you want to retrieve always. Then for the rest of the
attributes if you try to read them from the object you would have an
error, since they weren’t loaded from db.
So here comes the trick…
In your :select clause don’t forget to include the id as one of the
selected fields. That way you could use it to get the rest of the data
from db when you need it.
Easiest way of doing this would be a find with a select clause for your
blob/clob field.
obj=MyHeavyModel.find(:first,:select=>‘id,name,any_other_simple_fields’)
puts obj.id
puts obj.name
puts obj.blob_field #this would cause an exception since it’s not
loaded
puts MyHeavyModel.find(obj.id,:select=>‘blob_field’).blob_field #but
this would work
In case you have several blob/clob fields in your table, maybe you want
to reload them all directly. In that case you don’t even have to write a
new find, but just invoke reload over your object.The good thing is
reload will not take into account the original select clause, but
directly use the id to retrieve the complete row/object from database.
obj=MyHeavyModel.find(:first,:select=>‘id,name,any_other_simple_fields’)
puts obj.id
puts obj.name
puts obj.blob_field #this would cause an exception since it’s not
loaded
obj.reload #everything gets retrived from db, even not
previously selected fields
puts obj.blob_field #now you have here your field
Any of those solutions, should work fine, but you can still make it a
bit more transparent if the find/reload looks artificial in your code;
you could play with method_missing of your model so if it’s being called
for an attribute which is in your “column_names” list, it can
automatically reload/find the object and return the value of the
attribute back.
If you go with this approach, just take into account method_missing is
already overwritten in AR classes, so alias the old method and don’t
forget to call it before executing your part.
Regards,
Javier R.
Estamos de estreno… si necesitas llevar el control de tus gastos
visita http://www.gastosgem.com !!Es gratis!!