I want to create a lazy-loaded property that returns a collection on a Model, how do I do this?
I don’t want to create an association for this.
So I want it to return a collection, if the collection hasn’t been initialized yet then hit the database, return the rows, then initialize it.
If it get’s run once, then no need to run it again since the next page request will start things over.
Add an instance attribute (e.g.
@my_attribute)And then define
(Note:
initialize_my_attributeis a function/method you’ve implemented that will load the value you want.)How this works: the attribute starts out with a
nilvalue (we haven’t assigned anything to it). The object instance can’t access it directly, because we haven’t defined an attribute accessor on it. Instead we have a method that has the exact same name as the attribute, so that when you callmy_object.my_attributeit looks exactly as if you’re accessing the attribute when you’re actually calling the object instance’s method.What happens in the method? The
||=short hand is equivalent toSo if
@my_attributealready has value, that value is returned. Otherwise,@my_attributegets a value assigned (and then returned). In other words: the value will be loaded in@my_attributethe first time it is accessed (and only the first time).And voila! Lazy loading.