تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Follow Feature Overview0:00

You know, we have most of the functionality ready to go. The last main piece is following profiles. So let's get started with that. The first thing I want to do is take a look at the CreateFollows table migration, because I want to be sure that we had the unique setup so that we don't have any duplicate follows, just like the likes. And it's interesting to me that we remembered to do that. I say we that I remembered to do that.

And it's interesting to me that we remembered to do that. I say we that I remembered to do that with the follows table, but I didn't want the likes. So that's the first thing. The second thing is we need to be sure that a profile cannot follow itself. Now ideally we would approach this from both the database perspective and our code, but the database is, it is not problematic, but it's a little more involved.

but the database is, it is not problematic, but it's a little more involved because that uses the CHECK constraint, which most modern databases support. I mean MySQL, Microsoft SQL, PostgreSQL, Oracle, if you want to use that. Um, even SQLite supports CHECK. The problem is how you set up the CHECK constraint and that's a rabbit hole that we're just not gonna go into. So yes, ideally we would have

Testing Self-Follow Prevention1:17

and that's a rabbit hole that we're just not gonna go into. So yes, ideally we would have that constraint at the database level. So we need to be sure that our code takes that into account. And I think that's really the first thing that we need to test. So let's start by making a test of follow behavior test. And I'm just gonna copy the first few lines from our like behavior and we're gonna see a lot of similarities.

And I'm just gonna copy the first few lines from our Like behavior and we're gonna see a lot of similarities between likes and follows because you know, it is something that can be toggled. You, you either follow something or you unfollow it. So that's, that's how it is. Uh, so there are going to be a lot of similarities here. Let's open up the FollowBehaviorTest and let's paste this in so that our first test is, well, we don't need, like, we need the Follow model here.

and let's paste this in so that our first test is, well, we don't need, like, we need the Follow model here. So our first test is going to check that a Profile cannot follow itself and we need a Profile. We only need one in this case because we're just checking to make sure that it cannot follow itself. So we'll use our factory to create that. And then I want, you know, to follow the same kind of API that we've been using thus far, which is, you know,

And then I want, you know, to follow the same kind of API that we've been using thus far, which is, you know, these static methods. So that we would have something like follow and then createFollow. I don't necessarily like createFollow, but that follows in line with everything else. This is gonna get confusing. So we will have createFollow and we will supply two profiles.

So we will have create follow and we will supply two profiles. The first will be the follower, the second will be the follow. And then this should result in an exception really because we want to ensure that this doesn't happen. So I guess we should expect and we'll use a closure so that if we try to create a follow for the same profile,

and we'll use a closure so that if we try to create a follow for the same profile, then it will throw an InvalidArgumentException because, well is that really the best thing? Because we're passing arguments to it and you know, if they're invalid then they're invalid. Yeah. So we want an InvalidArgumentException. And let's say that the message will be 'Profile cannot follow itself.' That's very descriptive as to what that does.

Implementing createFollow Method3:37

a Profile cannot follow itself. That's very descriptive as to what that does. Alright, so that's basically what we need. Let's go to our Follow model and let's take a look here. We have fillable all ready to go. That's good. Uh, we have the follower and then following profile auntie, I guess that was gonna be following and I just let intelligence take over, which is never a good thing.

and I just let intelligence take over, which is never a good thing. But here we went to that public static function called create follow and we will have the follower profile and then the following profile because we, we don't want this to be any more confusing than it already is. That's gonna return self. And the very first thing we need to do is check to be sure

That's gonna return self. And the very first thing we need to do is check to be sure that the follower_id is the same as the following_id. Because if it is, then we want to throw a new InvalidArgumentException and our message will be 'Profile cannot follow itself.'. I'm pretty sure that's the message that we used inside of our test. So that's going to uh, at least be sure

that we used inside of our test. So that's going to uh, at least be sure that we can't follow ourselves. So then let's just go ahead and implement everything else. We are going to return static::firstOrCreate just like that we did with the likes because there's really nothing else that we need to do here. If there isn't a follow already set up, then you know, go ahead and create that and return that model. If there is one, then grab it from

go ahead and create that and return that model. If there is one, then grab it from the database and return it. You know that that's exactly what we want here. So our followerProfileId is going to be the followerId and then we just want essentially the same thing but for the followingProfileId. And there we go. We return that and everything's gonna be fine.

Testing Follow Relationships5:27

And there we go. We return that and everything's gonna be fine. So since we have this functionality, let's just go back to the test and let's test that we can create or we're not really creating here are we, we are ensuring that a Profile can follow another Profile. And what do we need? In this case, we need two Profiles and we'll just call it profileOne and profileTwo. And we will use that new method.

and we'll just call it profileOne and profileTwo. And we will use that new method that we just created is going to return a Follow model regardless of what happens. And then we will just pass in those two profiles. So the follower is profileOne, the following is profileTwo. So we need to test this from every angle. So we need to first of all ensure that profileOne, uh, what is the methods that we used?

So we need to first of all ensure that Profile one, uh, what is the methods that we used? We have followers and followings. Okay? So in this case it's gonna be followings contains the Profile two, we want to be sure that that is true. And then we want to test it from the other side so that we have Profile two has followers that contains Profile one. We want that to be true.

that contains Profile one. We want that to be true. So that way we test it from both sides of that relationship, if you will. But I also want to test this from the perspective of the Follow so that we have the followerId to be the ID of Profile one. And then the followingId will be the ID of Profile two. And I think that that covers pretty much everything.

of Profile two. And I think that that covers pretty much everything. We test it from Profile one, we test it from Profile two, we test it from the follow itself. So we should be able to come here and run our test. If I can type php artisan correctly and hopefully everything's gonna work. It does. We have 13 passing tests now and of course two of those are from the follow behavior test.

Implementing Unfollow Workflow7:30

and of course two of those are from the follow behavior test. Those pass. So now we essentially want to do the reverse. We want to unfollow and for the lack of a better word, we're gonna call this removeFollow because you know it is important to be consistent. So we will have removeFollow or once again we are going to pass in our profile and profile2.

or once again we are going to pass in our profile and profile too. But really we need to first of all create that follow so that we can then unfollow. So let's do that. We will create the follow, then we will remove the follow. And just like with the like this is going to return a boolean value to tell us yes it did. But after we remove the follow, we do need to be sure to refresh all of the information.

But after we remove the follow, we do need to be sure to refresh all of the information. But I think we will only need to do that for the follow object that we have. So as far as our expectations are concerned, we basically want to flip this so that uh, profileOne followings contains profileTwo should be false. And then profileTwo followers contains profileOne should be false as well. And then we want to ensure that the success variable.

be false as well. And then we want to ensure that the success variable that we have will be true. And really what we need to refresh here is our follow. And really after we do that, this should be null. So let's change this to null and that that's gonna be it. That way we once again test it from every angle, profile1, profile2 and the follow itself. So let's head on over to our Follow model so that we can have our removeFollow.

So let's head on over to our Follow model so that we can have our removeFollow. I want to call it unfollow, but removeFollow is in line with everything else. I don't know if we should continue to test if the followerId is the same as the followingId. And I guess we should because if we pass the same profile to removeFollow, we don't want to try to do any kind of database things because it's invalid. So we'll do the same thing so

of database things because it's invalid. So we'll do the same thing so that if it is the same profile, then we throw the exception, except that in this case cannot unfollow itself. We're not gonna test that because we pretty much know it works. Alright, so we have our removeFollow and we are going to do exactly what we did with the like functionality so that we are going to find the record where the followerProfileId is the same.

with the like functionality so that we are going to find the record where the followerProfileId is the same as the followerId and where the followingProfileId is the same as the followingId. So that then we can just delete it just like we did with the likes and we will return. If it's greater than zero, then yes that was successful and we would be good to go. So that means we should have everything ready to test.

Fixing Test Errors10:28

and we would be good to go. So that means we should have everything ready to test. We'll just run our tests. We now have, well, oh, uh, we didn't rename that test did we? Or did we? Profile can follow another. Yeah, profile can unfollow profile. Okay, but looks like we have an error here. Do we have an error? And yes, we do. It is syntax error right there, that comma. Okay.

Do we have an error? And yes, we do. It is a syntax error right there, that comma. Okay. But it definitely didn't like that. Okay, static where, followerProfile delete. But the problem is the return type because this needs to return a Boolean. All right, so that fixes that. We should be able to run this test now and hopefully everything passes.

We should be able to run this test now and hopefully everything passes and that means that we have all of the major functionality ready to go, which will make implementing our controllers a little bit easier. At least that's the theory. We'll see.

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