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

مرور کامنت‌ها و رأی‌ها0:00

(upbeat music) Okay, I think we've got our features built out pretty well and the backend is working pretty well, but now we're getting ready for that front end. We want our users to be able to come to the site, we want them to see what features we're thinking about building, vote on them, see the ones that have already been selected and whether they're done or not. So we want that nice front end, but before we get there,

Plan Comments and Votes0:22

and whether they're done or not. So we want that nice front end, but before we get there, there's really two things that those users are gonna be able to do on that front end. They can vote and they can comment. And so we need to create those data models, get it all set up on the backend, and it's kind of our last piece of backend work before we get to that front end. (whooshing)

Generate Models and Migrations0:40

before we get to that front end. (whooshing) So, let's go to our terminal and we're gonna start making models. We're going to make a comment model and we are gonna get a migration, a factory and a policy. I really wish you could just do P here, but that actually stands for pivot, not policy. So, it's a little few more characters to do this, but we will make a comment policy or model

So, it's a little few more characters to do this, but we will make a comment policy or model and all the things, and we're also going to make a model for vote in migration to factory and a policy as well. Okay, now if we go to our code, we have a bunch of new files here, and we're gonna start in the migrations where we want to make sure we get those migrations correct. So, we're gonna create comments table. We'll go here first, don't need that comment there.

So, we're gonna create comments table. We'll go here first, don't need that comment there. And so we have the ID. We're going to do a text for the body of the comment. It also is going to belong to a user. So we have the foreign ID for the user that's constrained. A comment is also going to belong to a feature. So, we have a foreign ID for feature ID. And then lastly, because it's a public site, we maybe don't want people posting whatever they want

And then lastly, because it's a public site, we maybe don't want people posting whatever they want and having it show up on our site. So, let's add a Boolean here for whether it is approved. The default's gonna be false. And so, when a comment comes in, we're gonna have to do some review on our backend to approve it before it actually shows to everyone. Okay, let's get rid of the down migration.

to approve it before it actually shows to everyone. Okay, let's get rid of the down migration. Don't need that. And now that we have this, we'll go to our comment factory. And define this quickly. Everything here looks pretty good. And then I want to do the policies all at the very end. So, let's get this votes table done. Create votes table.

So, let's get this votes table done. Create votes table. All right, this is gonna be pretty easy. All we need is the user in the feature. And we probably also want a unique. So, the user can only vote for one feature. And we do want the time stamps because then we can see kind of how the votes are going over time. Let's clean this up by getting rid of that comment

Add Admin User Flag3:02

the votes are going over time. Let's clean this up by getting rid of that comment and the down migration as well. It's nice and clean. And the vote factory is gonna also be very simple. Now, one other thing we're gonna have to do because now that we're adding this public part of our site, we need to know if the user is someone who has access to our admin panel, or if they're just a user

who has access to our admin panel, or if they're just a user who's gonna be able to write comments and vote on the front end. So, we're gonna have to make a change to our users. So, create users table. We're going to make some kind of a change here. Why don't we, I don't think we need full roles and permissions or anything. All we really need to know is table boolean

and permissions or anything. All we really need to know is table boolean and is admin, sure. So, by default, any user is not gonna be an admin, but the users that aren't admin will have access to the panel. So, we're gonna use that to manage panel access. We're also gonna use it to deal with our policies. So, the first thing we need to do is go to our user model. And this is something that you usually do

So, the first thing we need to do is go to our user model. And this is something that you usually do once you're getting ready to deploy your app to production and when you're gonna have real users, is we need to figure out are they allowed to access a panel. So, in order to do this, let's go ahead and look at the filament docs really quickly. If you go to the filament docs, you can find users. It's right here at the top.

If you go to the filament docs, you can find users. It's right here at the top. We need to implement this filament user contract. So, we have this here. We'll implement filament user. And what does that mean? It means we have to implement a method and the method is can access panel. So, we can copy this. I will put it below all of this.

So, we can copy this. I will put it below all of this. I think it belongs at the bottom. Can access a panel. We do need to make sure this panel is actually the correct one. We have a filament panel there. And then this is pretty easy because like we just said, return this is admin. So, you might need something more complicated.

because like we just said, return this is admin. So, you might need something more complicated. If you have multiple panels, some of the apps I build do have multiple panels. In this case, every panel, no matter what is passed through here, we're just gonna return that they can see it if they're an admin and they cannot see it, they're not an admin. Because the front end of our site

Define Authorization Policies5:23

they're not an admin. Because the front end of our site is not gonna be a panel. It's just gonna be a public live wire component. So, we don't need to worry about blocking people from that front end side. It's just the panels. Now, this is also going to be very useful as we are determining the policies, which is what I want to move to next.

as we are determining the policies, which is what I want to move to next. So, I'm going to go take this, copy it, 'cause I'm gonna use it a lot. Let's first go to our feature policy. And if you look at all this stuff, can you view any features? Yes, if I'm on the front end of the site, I wanna be able to view them. So, we'll just return true for everyone.

I wanna be able to view them. So, we'll just return true for everyone. We will also have a page where you can view one specific feature on the front end. So, view is there too. Our users are not going to be able to, or our front end users are not gonna be able to create. So, I'm going to say user is admin, not this. So, I'm gonna copy this

So, I'm going to say user is admin, not this. So, I'm gonna copy this and we're probably gonna use this a lot here. Can you update a feature? Not if you are just on the front end. So, it doesn't really matter. We're not gonna implement who owns what feature. If we were, we might check if you're the feature owner and then allow you to do it. But, in this case, it's just really simple.

and then allow you to do it. But, in this case, it's just really simple. Are you able to view the admin panel or not? Delete, same thing, delete any, same thing. These are all probably going to just be for people on the admin panel. And this one, we added that before, but we don't need it. So, we have this and this is good. There are a few other policies that you might have to add if we start adding things like bulk actions

There are a few other policies that you might have to add if we start adding things like bulk actions because there's different policy methods for that. But we're fine here on the feature policy. Let's go to the comment policy. This one's gonna be a little more permissive. On the front end, they're gonna be able to view comments and they can create comments. We probably don't want them to update their comments once they've made a comment.

We probably don't want them to update their comments once they've made a comment. We can just say, so this would be true. I didn't realize these were all false. So, these are true. Let's see, on the update side, let's just say, we'll do, you can only update if you're an admin, delete, same thing, and these are gonna be admin as well. Okay, and then finally, we want to look at the vote policy. So, who's gonna be able to view votes, I think?

Okay, and then finally, we want to look at the vote policy. So, who's gonna be able to view votes, I think? For the most part, this is gonna be true for everything, just because if you're the user who did the vote, if you want to decide you don't want to vote for that feature after all, I think you should be allowed to do that. So, I don't think we really need any restrictions. You can, everyone can see who voted for what and even delete their own.

You can, everyone can see who voted for what and even delete their own. I guess the one thing for delete, we would say, if vote user ID is the user will return true, and then otherwise we'll return user is admin. So, an admin can delete anyone's vote, but if I am the one who voted, then I can only delete my own vote. So, I think that makes a lot of sense. This forced delete, we'll just say false there,

Set Model Relationships8:50

So, I think that makes a lot of sense. This forced delete, we'll just say false there, just for some security, but I think everything else here is pretty good, we might find we have to come in here and tweak this a little bit more, but I think our policies are in a good spot now. The next thing we need to do is set up the relationships on the models. So, if we go to the feature model, we're gonna have a few things.

So, if we go to the feature model, we're gonna have a few things. We have a feature has many comments, and a feature also has many votes, okay? And then these are pretty simple, a comment belongs to a user, and then if we go back to user and then get down here to the bottom, a user has many comments, oops. We have comment and don't need the S there. And then if we go back to, I think the feature,

We have comment and don't need the S there. And then if we go back to, I think the feature, and if we go back to the comment, the comment belongs to a user, it also belongs to a feature. And then we also have our vote model. So a vote belongs to user belongs to feature. Okay, I think I got everything. Oh, a user has many votes, and they have many comments, so I need to do that.

Oh, a user has many votes, and they have many comments, so I need to do that. I think I've got everything here, so now let's go ahead and run our migrations, and once we've run our migrations, then we can also generate a filament resource, probably just for the comments. I don't know that we need a filament resource for the votes, but I don't know, maybe we do. Let's just start with migrate.

Build Filament Resources and Managers11:11

but I don't know, maybe we do. Let's just start with migrate. So PHP artisan migrate. All right, we've created that. Okay, and let's go ahead and make the filament resource. It's not feature, it's gonna be comment. And we'll generate, what did we name the comments? So create comments table. We're gonna find that right here. We named it body.

We're gonna find that right here. We named it body. So we go back to our terminal. The title attribute is, you know, the title attribute, maybe is the ID, the body is gonna be very, very long. We'll just call the title attribute the ID. We don't need a read-only page for the resource. And then let's also do another resource, just to see what it looks like. We could delete it if we don't like it for vote.

just to see what it looks like. We could delete it if we don't like it for vote. And this one's gonna be really simple ID as well, and we don't need a view-only page. So now let's get back into our app. And I refresh the page here. Can access panel must be of type Boolean, and null is returned. Okay, so I think this is because we did not migrate fresh our database.

Okay, so I think this is because we did not migrate fresh our database. So we need to do that, but we also have to make sure that when we seed our database, that the user that we start with, we're gonna say is admin is true. Okay, so now we'll go back to the terminal, migrate fresh seed, and refresh the page. I'm gonna have to log in again. And so now that I'm here, I've got my dashboard, I've got comments.

And so now that I'm here, I've got my dashboard, I've got comments. We've got this logic exception here, and this is again checking. We saw this before in the earlier video that there's a delete any method found on the policy. So there are two ways to solve this. We did this before if I go to my comment policy and I can add a delete any here. The other thing I can do is go to my comment resource.

and I can add a delete any here. The other thing I can do is go to my comment resource. And if I look at the comments table, you see there's a bulk action here for delete. If I comment that out and then come back here, it's gonna allow me to see it. So if I'm not giving you the action to do a bulk delete, then I don't have to check if bulk delete is allowed. So let's just say we're not going to bulk delete comments so we can just leave it like that.

So let's just say we're not going to bulk delete comments so we can just leave it like that. And maybe the same thing for votes. So if I go to the votes table, we can comment that out and then we don't have to worry about the policy for that. So we have votes and comments. But one thing is we can change these icons. We probably want that to look a little bit different. So if we go, let's start with the votes. Go to the vote resource.

So if we go, let's start with the votes. Go to the vote resource. And it starts with the outlined rectangle stack. We have these heroicon enums. So we can pick whatever we like here. We have outlined hand, thumb up. So we'll do that. And then let's also go to the comment resource. We've got something here. This would be outlined.

We've got something here. This would be outlined. Chat bubble left, right? Sure. And then our feature also needs something. So feature resource. Go to the top. Star sounds good. All right, so now we refresh and we've got this working.

All right, so now we refresh and we've got this working. I probably also want features above comments. So you can see that we can add an order. So, or I think it's navigation sort. So I call this one and then go to comment resource. We'll make this two. And then vote, sorry, vote resource. This is gonna be three. So now if I go to my browser and refresh, there we go.

This is gonna be three. So now if I go to my browser and refresh, there we go. This is in the order I like now. Now I might want to see comments and votes by themselves, but I think the primary way I would like to see this is in relation to a feature. And so what I want to do is create a relation manager that will allow me to see all of the comments for a specific feature. So when I'm here and I'm viewing my feature,

for a specific feature. So when I'm here and I'm viewing my feature, I will have a table down here that shows me all the comments related to it. Let's do that now. Filament makes it pretty easy. We'll do make filaments relation manager. And I can just let the prompts walk me through this. So which resource is the relation manager in? It's going to be in the feature resource

So which resource is the relation manager in? It's going to be in the feature resource and the relationship is comments. So you can see this is asking if you want to link the relation manager to the existing resource. We can go ahead and do this. And the resource we want to use in this case is the comments. So now if we go and take a look at what was created here, we have a comments relation manager. So I know there's tons of new files here,

we have a comments relation manager. So I know there's tons of new files here, but let's take a look at that comments relation manager. So you can see we have this here. And the other thing that we just want to do is use that comments relation manager. So the feature resource we've got here to get relations. I want to do comment relations manager. So we do that and now if I look at my features, I've got the comments down here.

So we do that and now if I look at my features, I've got the comments down here. And this would show me who is the user. We probably don't need the feature because we're on this page itself. So that column is not going to be necessary. And we can see if the comment has been approved or not. So let's go into the comments relation manager here. We have the table and the table is pulling from the comment resource where we have the table configured here.

We have the table and the table is pulling from the comment resource where we have the table configured here. But like I said, we don't want this feature to be shown when I'm on the feature page itself. Okay, so if we want this hidden on that relation manager, what we can do is come here and say hidden on and we can say the comments relation manager, pass this class in here. And then this is going to not be visible when we're on the comments relation manager.

And then this is going to not be visible when we're on the comments relation manager. So if I refresh and scroll down, you can see it's no longer here. But if I go to comments, it is here. Now this might be what you want, but I do want to warn you that in a bigger app, you might have the same relation manager that you're using in a bunch of different places. And so you might need to be a little more specific

that you're using in a bunch of different places. And so you might need to be a little more specific about when I want that column hidden or visible. But in this case, because that's the only place the relation manager is ever going to show, then this works just fine. So when I pull this up, I don't see the feature name in the table. Let's just clean this up here as well. We'll just say approved, or sorry, label is approved.

Let's just clean this up here as well. We'll just say approved, or sorry, label is approved. It is an icon column, so it'll be a check or an X depending on whether it's been approved. So probably the other thing we want to do is make a relation manager for the votes as well. So we'll make filament relation manager, we'll do the same thing here, votes. Oh, actually, sorry, I'm going too fast. So we will make a relation manager.

Oh, actually, sorry, I'm going too fast. So we will make a relation manager. It's going to be the resource we're creating it in is again, features. The relationship is votes. And we can link it to the vote resource and which resource do we want to use? In this case, it's votes. So now we'll go back to the feature resource. And we're going to add another relation manager

So now we'll go back to the feature resource. And we're going to add another relation manager called votes relation manager. And we need to make sure that's imported. And then if we go back to the browser, now you can see this is nice where we have two different relation managers. So it's going to allow us to click from one to the other. And we'll do that same thing where we don't need the feature to show there.

And we'll do that same thing where we don't need the feature to show there. So if we go to the votes relation manager, which is actually pulling from the vote resource, and we go to the table. And same thing, feature name, and we will just say hidden on. And this will be votes relation manager class. And now it is no longer showing there. So this will just really give you the user

And now it is no longer showing there. So this will just really give you the user that voted for that feature. Okay, now the best way to just test this and take a look at it and see what's going on is let's just use those factories that we created. So we have the comment factory. Everything here is good. So let's go ahead and open up Tinkerwell. And here in Tinkerwell,

So let's go ahead and open up Tinkerwell. And here in Tinkerwell, let's try by factoring up a few users. Let's do this. And let's look at our database and see that it's looking good there. Here's my roadmap database. I go to users. I've got three more and none of them are admins. So that's good.

I've got three more and none of them are admins. So that's good. Now, if we go back to Tinkerwell, we can say, you know, comment factory. We'll make three. And let's have the feature ID is, I don't know, three. And user ID is two. Okay, so we've got some comments here. Now, if I go to my features

Okay, so we've got some comments here. Now, if I go to my features and I don't have the ID column, let's just go to a feature and I can actually find just by going to three right here. If I look at this one, I do have some comments here. Now, one thing I don't have in the table is the actual content of the comment. So let's go to the comment resource

is the actual content of the comment. So let's go to the comment resource and look at our table. And for some reason, the let's see, text column make content. We can give it a limit of 50. You can make it searchable. And now if I refresh, here's the content. Now, why is it blank? Let's take the limit off and just see.

Now, why is it blank? Let's take the limit off and just see. Or no, sorry, it's not the content. I think we called it body. That's why. All right, we'll give it a limit of 50. And here we go. So this is kind of nice where you can limit. This would be maybe a really long comment. Maybe we don't want to see all of it.

This would be maybe a really long comment. Maybe we don't want to see all of it. So that limit option gives us that ability. And so we can see what the comments are on each roadmap item here. Now, just to finish up, let's make sure votes are working. We'll go back to Tinkerwell. In this case, maybe we can just let the vote factory spin up a bunch of users for us.

In this case, maybe we can just let the vote factory spin up a bunch of users for us. We'll stay with feature ID three. And we'll just let, I don't know, let's get 20 votes on this guy. And now, if I refresh this page, I've got all these 20 people that have voted for this one feature. Okay, I think our data structure is working. We've got features, comments, and votes.

Okay, I think our data structure is working. We've got features, comments, and votes. And it all works on the back end. Now it's time to do it on the front end.

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