In this post, I covered from minute 3:33:55 until 3:46:33 of this video.
In previous part, we already made a pivot table to connect Profile and User
model. We now need to set up the relationship.
Set up relationship
We need to define that a user belongs to many profile and a profile belongs to
many users. We name the method following and followers respectively.
62 63 64 65 |
public function following() { return $this->belongsToMany(Profile::class); } |
app > Models > User.php
20 21 22 23 |
public function followers() { return $this->belongsToMany(User::class); } |
app > Models > Profile.php
Attach and detach relationship
So how do we connect a profile to another profile when a user click the
'Follow' button, and if we click the same button again, it will disconnect?
For this, we're going to use Laravel method called toggle. So let's go ahead
and open the Follows controller.
We need to return the authenticated user, fetch the following relationship and
call the toggle method. What are we toggling (connect/disconnect)? We are
toggling the user's profile. Remember, the user that we are referring to
in the function is NOT the authenticated user, but the user that is passed
into. In below code, is how we use the authenticated user to create that
connection with a user's profile.
10 11 12 13 14 |
public function store(User $user) { //Attach and detach user's profile return auth()->user()->following()->toggle($user->profile); } |
app > Http > Controllers > FollowsController.php
You should be getting an alert :
127.0.0.1:8000 says: [object Object]
. To see the attach and
detach works, let's change alert
to console.log
in
the component (FollowButton.vue). After that, try clicking the button
again.
The first time I click the button, it attach the profile of user with id 2 to
user aliya.h, it means that I successfully follow that user. The second time I
click, it detach the profile, meaning that I have unfollow it. We can check if
the connection is actually created by using tinker.
Change button state
Right now, we can only know if we have successfully follow a profile through
the console log, so we need to change the text for the follow button, as well
as set the initial state for every user. What we want to do is set the initial
state as 'detached' with button text 'Follow' and change the text to
'Unfollow' once the it is 'attached'.
1) How do we determine if a user is following a profile? This is what this
code does.
11 12 13 14 15 16 |
public function index(User $user) { $follows = (auth()->user()) ? auth()->user()->following->contains($user->id) : false; return view('profiles/index', compact('user', 'follows')); } |
app > Http > Controllers > ProfilesController.php
Translation: If a user is authenticated ( auth()->user()) ), then ( ? )
grab the authenticated user's following
( auth()->user()->following-> ) contains the user (
contains($user->id) ) that are passed in (User $user). Otherwise ( : ),
just return false (not following).
2) Pass the status to the view and change the state of the button
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<template> <div> <button class="btn btn-primary btn btn-primary btn-sm pl-4 pr-4 ml-3" style="font-weight:500" @click="followUser" v-text="buttonText"></button> </div> </template> <script> import axios from 'axios' export default { props: ['userId', 'follows'], mounted() { console.log('Component mounted.') }, data: function () { return { status: this.follows, } }, methods: { followUser() { axios.post('/follow/' + this.userId) .then(response => { this.status = !this.status; console.log(response.data); }); } }, computed: { buttonText() { return (this.status) ? 'Unfollow' : 'Follow'; } } } </script> |
resources > js > components > FollowButton.vue
3) Call the 'follow' status to the view
13 |
<follow-button user-id="{{ $user->id }}" follows="{{ $follows }}"></follow-button>
|
resources > views > profiles > index.blade.php
Redirect unauthorized user
When someone is logged out, they can still hit the follow button. But instead
of letting the app send a 500 error to the console log, we should return a 401
(unauthorized) error and redirect them to the login page.
1 2 3 4 5 6 7 8 9 10 11 12 13 | class FollowsController extends Controller { public function __construct() { $this->middleware('auth'); } public function store(User $user) { //Attach and detach user's profile return auth()->user()->following()->toggle($user->profile); } } |
app > Http > Controllers > FollowsController.php
24 25 26 27 28 29 30 31 32 34 35 36 37 38 39 | methods: {
followUser() {
axios.post('/follow/' + this.userId)
.then(response => {
this.status = !this.status;
console.log(response.data);
})
.catch(errors => {
if (errors.response.status == 401) {
window.location = '/login';
}
});
}
},
|
resources > js > components > FollowButton.vue
That is all for this part. On the next part, we gonna learn how to count the following.
No comments:
Post a Comment