در حال بارگذاری ...

Starting With a Test0:30

We're going to do it together, each video, in real time. Okay, so with that in mind, for all things like this, I begin with a test. It's almost like my scratch file to figure out how I want it to work. So I'm going to make a new test here, and I'm going to call it Achievements, okay? And we will begin. Now this is always a tricky step, right? Beginning is always the hardest step, I think, because you're left with this decision of where do I start? I don't even really know how it should behave yet. How am I supposed to write a test to prove that code I don't even understand or recognize?

Defining Achievement Criteria1:00

I don't even really know how it should behave yet. How am I supposed to write a test to prove that code I don't even understand or recognize yet works, right? It's a tricky thing. And this is where the idea of examples really comes into play. Let's just provide an example for what we want to do. And then from there on, we can work and flesh out the API. So the first example I might have is, a User earns an Achievement badge when they hit a thousand points of experience. So how about an Achievement is earned once a User's experiencePoints pass 1,000.

Considering Event-Driven Awarding1:25

thousand points of experience. So how about an Achievement is earned once a User's experience points pass 1,000. Now experience is something that I already have implemented on the site. As you watch videos, or create forum threads, or reply to forum threads, or leave a reply that is marked as the best possible answer, all of these things will award you experience. So it sounds like we need a listener class that listens for each time experience is awarded to a User. And when that takes place, maybe we'll do a little check. Is it time now to award the User a badge? But yeah, really, there's many, many different ways we could do this.

Is it time now to award the User a badge? But yeah, really, there's many, many different ways we could do this. We could also isolate it, where maybe we have a job that runs once a day, where we go through all the users and we just do a handful of checks to figure out which badges they should be awarded. That would be another approach, but I'm not sure that's what I want to do. So instead, where do we get started? Well, we need to create the world, right? Create the world for the test. So I'm going to quickly whip up a User, like so.

Create the world for the test. So I'm going to quickly whip up a User, like so. And I want to assume that the User has been awarded experience. And of course, if I'm creating a User, their experience count is zero. So I'm going to award them, at least for the sake of the test, 1001 points, just to make sure that I trigger whatever I need to take place. Okay, so I can do that with my API saying, give me the experience and we will award. So when I call this method right here, it's actually giving me an instance of this Experience class, which extends from Eloquent. So it does have a table.

class, which extends from Eloquent. So it does have a table. And there's a method here where I'm just incrementing a points column. Okay, so we're going to award experience 1001. Now ideally, that should trigger some kind of event, at least to start. Yeah, maybe when a User is awarded experience, we should trigger an event. And I'm not yet doing that at the moment. So that's something to think about. But nonetheless, this is basically the world I want. Given I have a User, when I award the User enough experience to pass a certain threshold,

But nonetheless, this is basically the world I want. Given I have a User, when I award the User enough experience to pass a certain threshold, in this case 1000 points, then what should happen? Well, I create the world when this takes place, then the User can unlock a new achievement. Yeah, maybe that's the terminology. This was important too, even though whether you earn an achievement or you unlock an achievement or you are awarded a badge, these all basically mean the same thing. But it's important that you decide what terminology you're using, because those words you choose will end up in the code. All right.

will end up in the code. All right. So I'm going to say an Achievement is unlocked once a User's experiencePoints pass 1000. Yeah, an AchievementBadge. Yeah, I'm still deciding. Do I call it a badge? Do I call it an achievement? Is it an achievement badge? Do we keep it simple? These are all important things that you got to take time to think about.

Designing Achievement Data Model4:31

Do we keep it simple? These are all important things that you got to take time to think about. Anyways, how can we verify that the User has unlocked a new achievement? I'm thinking we're going to have some kind of table where we record the achievement. And again, I'm not ahead of you at all here. I'm thinking about this on the fly as I record. So to start, maybe we have a dedicated achievements table that consists of the userId of the person receiving the achievement. And you know what? Maybe this is a pivot table.

And you know what? Maybe this is a pivot table. So maybe we also have the achievement_id instead. Yeah. So maybe this is a user_achievements pivot table. We have one column to track down the associated User, another column to track down the associated Achievement. So that would have the ID there that this would correspond to. And maybe what else would be a part of the Achievement? So let's just think of it together.

And maybe what else would be a part of the achievement? So let's just think of it together. If we have this concept of an Achievement, well, yes, it has an ID, probably has a name, something like, you know, something silly like the moving on up badge. You know, once you are awarded 1000 points, you unlock this badge, and maybe each badge has an associated icon. You know, this would be moving up.svg or something like that. Now we're not storing the image itself. Of course, we're only going to store a path to where that icon would be. What else here?

Of course, we're only going to store a path to where that icon would be. What else here? Maybe we need some more specifics. Because if I'm looking in a database table, and I just see a bunch of achievements like this, I don't even know what moving on up. That's made up, by the way, that's not a real badge. But I don't even know what that would refer to. So maybe we also want to add a little description, like a text column as part of that earned when experience points pass 1000, you know, something like that. So does this all make sense?

when experience points pass 1000, you know, something like that. So does this all make sense? I think this is okay. So you'd have your user table that has your ID column, you'd have an achievements table. And then you would have a user_achievements lookup table or a pivot table. And this is where we actually create the relationships where we can say, all right, the user with an ID of 400 just unlocked the achievement with an ID of 1. And, you know, maybe this ID is 1 here. So we can say, all right, this guy just unlocked this badge, then the API can be something along the lines of this.

So we can say, all right, this guy just unlocked this badge, then the API can be something along the lines of this. So yeah, notice this is exactly what I mean when I say I think of the test class as my scratch file. Yes, we're going to write actual code to figure out through examples how we want things to work. But it's also a place to just to just tinker to get something on the page and figure out how do we want this to work sort of like a whiteboard. Okay, so if we switch back our verification, now, clearly, we have a lot to do, right? We need to create two different tables there, which means we'll need migrations and all.

Planning Assertions and Migrations7:21

Okay, so if we switch back our verification, now, clearly, we have a lot to do, right? We need to create two different tables there, which means we'll need migrations and all of that stuff. So this will take a little while. But if I scroll up, ultimately, my check will be user, we said we wanted to call achievements. That would give us all achievements that the user has been awarded or the user has unlocked whatever terminology we choose. And maybe at least to start, let's just ensure that we have at least one achievement, given this action that takes place here. So at the moment, if I give this a run, argument two of assertCount should be countable, but

Broadcasting Experience Award Events8:53

do we make an announcement in our code base and it's sounding like that's something I need to do. When a User is awarded experience, I want to hold up a bullhorn and say to my entire code base, hey, if anyone cares, I just awarded experience to this User, do what you must. And in our example, we're going to set up a listener and say, all right, let's check those points. Did it pass a threshold? If so, we need to award this User an achievement or a badge or unlock a badge. We don't yet know the terminology. We're figuring this all out together.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟