Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a lazy loaded property in Ruby for a Model?

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.

like image 423
Blankman Avatar asked Mar 07 '11 16:03

Blankman


People also ask

How do you implement lazy loading?

To lazy load an image, display a lightweight placeholder image, and replace with the real full-size image on scroll. There are several technical approaches to lazy loading images: Inline <img> tags, using JavaScript to populate the tag if image is in viewport. Event handlers such as scroll or resize.

What is lazy loading in Ruby?

When you have an object associated with many objects like a User has many Friends and you want to display a list as in Orkut you fire as many queries as there are friends, plus one for the object itself. users = User.find(:all)

What is lazy code loading?

Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.

What is difference between lazy loading and eager loading?

Lazy loading in Entity Framework is the default phenomenon that happens for loading and accessing the related entities. However, eager loading is referred to the practice of force-loading all these relations.


1 Answers

Add an instance attribute (e.g. @my_attribute)

And then define

def my_attribute
  @my_attribute ||= initialize_my_attribute
end

(Note: initialize_my_attribute is a function/method you've implemented that will load the value you want.)

How this works: the attribute starts out with a nil value (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 call my_object.my_attribute it 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 to

@my_attribute = (@my_attribute || initialize_my_attribute)

So if @my_attribute already has value, that value is returned. Otherwise, @my_attribute gets a value assigned (and then returned). In other words: the value will be loaded in @my_attribute the first time it is accessed (and only the first time).

And voila! Lazy loading.

like image 149
David Sulc Avatar answered Oct 24 '22 18:10

David Sulc