⚠️ This lesson is retired and might contain outdated information.

Add Caching to the Model Base Class

Brett Cassette
InstructorBrett Cassette
Share this video with your friends

Social Share Links

Send Tweet
Published 10 years ago
Updated 2 years ago

In the previous lessons we created a base class and looked at a caching mechanism for our models. In this lesson we will expand on that concept by test driving the addition of caching to our model base class, as well as some initial core functionality. This is advanced subject matter, and will require study of the code as well as watching the video.

Instructor: In our previous video, we saw why caching is the first thing that we want to add to our base class.

Let's go ahead and make sure that our post inherits from base-class.base. base-class is going to be the name space that the base module, which is our actual base class, will live in. While we're here, what we're going to do is go ahead and let the post instantiate with attributes. Let's say this.id = attributes.id. This will be the primary key. Again, that's useful in caching.

Let's go ahead and write our first test. I've added a caching spec for us. The first thing is, it adds a cache to the model. We want to expect post.cached should equal an empty object. It will start out as an empty object. Here we see undefined. We expect it to equal an empty object. That's because post doesn't yet have a cached property.

Let's go ahead and create the cache. In a previous video, you saw that we created this constructor and prototype on one of our mocks. Here we added it to our actual base class. What we're going to say is that the constructor, which will be the post model, dot cached equals new cache. We're going to create a cached model here. That will be called bc-cache, and we'll have that live in its own file. We'll inject it here.

Now we see. We have no bc-cache provider. Let's go ahead and create a home for our cache. Again, we're going to add a cache folder and a cache file. This is, real quick, going to be in the module base class. We're going to create a factory called bc-cache because that's what we called it. All we need to do here is to create a constructor for our cache and go ahead and return that constructor. Now our tests pass.

Let's go ahead and create our next test here. We'll copy this guy out. We're going to expect that it adds new instances to the cache when they are created. We're going to say that, when we call post.new with an ID of one, then we expect post.cached to equal post. If we look up the first post, it should be this post with the ID of one. We see that this fails because we don't have a post.new method.

Let's go ahead and add that method. I'm going to bring in some code that we created in a previous video where we add this new method to the constructor. Now we're going to have a different error. We expected undefined to equal the first post with an ID of one.

We want to go ahead and cache that instance. To do that, we have to create a cache method which takes an instance. This will abstract some of the functionality here of the constructor.cached. We'll add a cache method to that, which will take an instance and a primary key.

The primary key will be defined on the constructor. This will allow the user to say the primary key is ID or it's _ID. We'll give it a default in a second. That will look up the instance.ID, which will be the primary key out of the box. It will say cache the instance with ID of one or return the instance with ID of one.

Here we se that we don't have a cache method on the cache. Also, we're going to need to add this constructor.primary-key because otherwise that will be undefined.

This primary key we're going to want to define is a private variable that will exist on the constructor like the post model, but we don't want it to be a enumerated over because we don't want users of our base class to see it.

What we're do here is abstract what it means to have a private method into a global function here. We're going to take the name of an object, the name of an attribute, and then a value to assign to that. That will create our private variable for us. This is adding some boilerplate for us.

What we're going to here is, we're going to say "private variable." We're going to add this to the constructor, and we're going to call it primary-key. This will be the value of the primary key out of the box. We'll say that it's ID because that's what most primary keys are.

Again, we're still seeing that we don't have a cache method on the cached object. Let's go ahead and add this to our cache here. This is going to be a private variable as well because we don't want it to be exposed on the cache itself. We'll say "cache instance." It will take a primary and an instance.

If the instance exists and the primary key of that instance is not equal to undefined -- meaning it could be zero, it could be one, anything else -- then we're going to want to add the number as the key. Instance primary key is equal to this instance. That will go ahead and add it to the cache. We see this makes it pass.

The final thing we want is for our cache to be queryable. We want to say that if we have a post that we've added here, and we search for it, and we say where the ID equals one, we want it to return an array of post, where post is the only object in there. If we queried for other things, like maybe the title of the post or the author of the post as a certain thing, we might want this to be a number of objects where it's post one, two, and three, something along those lines.

We want it to find items in the cache via parameters that we pass in. This is going to be really useful for us in the future. Here we see we have no method "where."

Let's go ahead and make this pass. We're going to do this using LoDash. We're going to define the final private variable. It's going to be called "where." Again, it's going to be a function. This function is going to take some search terms.

We're going to return LoDash.where. This has the terms. We're going to pass in "this is the context." Again, this is going to run a simple query on that object, and find the cached instance where the search parameters are true.

Now we've added caching to our base class. We've thoroughly tested it. Now it's time to move on to the next video and keep building.

Kevin
Kevin
~ 10 years ago

I'm having a hard time following the definition of the privateVariable, particularly how it's setting up accessors.

The use of val variable throughout the function confuses me; I'm confused why value isn't used for get and set instead. The get seems like it'll throw undefined if it wasn't for the if statement at the end of the function (if (value !== undefined) object[name] = value;)

The existence of that particular if statement actually also confuses me because it seems like it should be a conditional statement inside of get instead of being outside the function.

For additional educational purposes, why wouldn't a data property attribute definition wouldn't work?

Within the privateVariable function, the following code snippet probably would work seemingly:

Object.defineProperty(object, name, {
  enumerable: true,
  configurable: false,
  value: value,
  writable: true
}

// value could also take a function that can return value after conditional statements, like checking if it's undefined to perhaps throw an exception or something...
Grégory
Grégory
~ 8 years ago

The videos "full resource" do not open here. Codec? All others are normal.

Grégory
Grégory
~ 8 years ago

Sorry, my download manager converted the extension .zip for mp4

valery
valery
~ 8 years ago

Hi Guys,

First of all, thank you for your hard work. Could you help me, I can't download source code for this and other lessons from this playlist. When I click "available for download" link the browser starts downloading of related video instead of source code.

Thanks.

Markdown supported.
Become a member to join the discussionEnroll Today