Extending Voting to Comments0:00
So I just wanted to make a quick video discussing some alternative implementation details for the voting feature that we just completed. So right now we can vote for ideas, but say, for example, we can also vote for comments here. So how would we implement that? We could do basically the same thing that we did for voting for ideas. So we can have a new model. We have to name it something else because vote is already taken. And then we need another table. So again, name has to be different, vote_comments or something like that.
Using Polymorphic Votes0:25
And then we need another table. So again, name has to be different, voteComments or something like that. And the only difference would be ideaID would now be commentID and everything else would be the same as this. So we still have a userID in this column. So that's fine. You can keep it separate if you like. But we also have an option to create a polymorphic relationship. So in that case, we would add a new column here called votableType. And then instead of ideaID, we would just have votableID.
So in that case, we would add a new column here called votable_type. And then instead of idea_id, we would just have votable_id. So anything that's votable, their ID would go in here and then Laravel will be responsible for instantiating the correct model since we have that new votable_type column here. So given this approach, we can store everything in this table. Also the votes for ideas and the votes for comments as well. So again, extra column here called votable_type, change this to votable_id. And then we have to change some of the relationships we have in our models. So obviously we'd have a Comment model as well, but we haven't gotten there yet. So I don't have a Comment model, but we just have to switch our belongsToMany relationships.
Updating Morph Relationships1:29
So obviously we'd have a Comment model as well, but we haven't gotten there yet. So I don't have a Comment model, but we just have to switch our belongsToMany relationships. So right now I'm in my User model. And instead of a belongsToMany relationship, we would use a morphToMany relationship. So like this morphToMany, I guess. And the second parameter is the relationship. So now it's a votable. And for our Idea, same thing. We can change this to a morphToMany relationship. And this would be votable as well.
Choosing Terminology Approach2:00
We can change this to a morphToMany relationship. And this would be votable as well. Now, if you were to ask me if I would personally use a polymorphic relationship in this case, that would depend on the terminology being used. So if you look at the Laracasts form, there is the ability to like a Comment or heart a Comment. It's using this heart icon here. And if we were to implement this in our app, I think we would have something similar to stay consistent with the Laracasts form. So it will be a heart, not really a vote, even though there's the same thing.
stay consistent with the laracasts form. So it will be a heart, not really a vote, even though there's the same thing. So the terminology would be different. So for me, I would probably just make a new model named like Heart, and that would be dedicated to comments. And then I would have two separate tables for likes for ideas and likes for comments, mostly because the terminology is different. Sorry, I said likes, but I meant votes. So voting for ideas and liking comments. However, if the terminology was the same for both, for example, if they were likes instead.
Replacing Lookup Tables with Constants2:55
So voting for ideas and liking comments. However, if the terminology was the same for both, for example, if they were likes instead of votes, and likes for comments as well, I would be more inclined to use a polymorphic relationship and just one table. So yeah, for smaller apps like this, I think it's more of a personal preference, and it doesn't matter too much, in my opinion. Okay. The next thing I want to discuss is using constants for models that don't change often. So for our categories and our statuses, we have a oneToMany relationship between ideas and categories and ideas and statuses.
So for our categories and our statuses, we have a one to many relationship between Ideas and Categorys and Ideas and Statuses. So if you look in our database, we have a statuses table, and we also have a categories table. Now, once you decide on this, it doesn't change very often. It will sometimes, but obviously not as often as something like the votes table or the ideas table. So what we can do is remove these models and database tables completely and just store them as constants on the model. So we would get rid of these categories and statuses.
them as constants on the model. So we would get rid of these categories and statuses. And here on the idea table, we can get rid of them here as well and actually not get rid of them, but change them to a category and a status and store the actual category and status directly on here. And then we can go to our Idea model. We can get rid of these relationships here, and then we can maybe store them on constants. So for example, for categories, we can have, let's say we had two categories, say one for prepended with category, say one for tutorial requests, and store a string tutorial request. And this is what would get stored in the database on the idea table.
prepended with category, say one for tutorial requests, and store a string tutorial request. And this is what would get stored in the database on the idea table. And then say we had another one for a Laracasts feature, and we can also store the corresponding Okay. So now, like I said, we are no longer using the database for categories and statuses. So that would reduce the overall number of queries that we're performing here. And some would also argue that seeing the categories directly in the code makes it easier to read as opposed to storing it in the database. So yeah, those are some pros of using this approach. So some cons of using this approach, we lose the ability to make use of Eloquent because
So yeah, those are some pros of using this approach. So some cons of using this approach, we lose the ability to make use of Eloquent because now they are just constants on the model itself. Also we now have to push code whenever we want to update one of these categories or add a new category, which isn't too much of a con if the developer is the admin. But if the admin is not a developer and cannot push code, then they cannot update the categories themselves. So yeah, this is an alternative approach if you know your models aren't going to change very often. So one more thing I want to discuss is another way to store the votes count.
Storing Vote Counts Column5:48
very often. So one more thing I want to discuss is another way to store the votes count. So if you remember, we are grabbing the votes count using the withVotes Laravel method. So I believe that's an IdeaController right here with count. And under the hood, this performs a sub query, and then we can access it as if it were a real column on the database. So another approach would be to actually store a votes count field directly on the database itself. So a real column on the database on the table, I mean. So on our ideas table, we create a new one here called the votes count, and it would
So a real column on the database on the table, I mean. So on our ideas table, we create a new one here called the votes_count, and it would be zero to begin with. But then we would increment or decrement that votes_count every time a User votes on an Idea. So if we take this approach, we can get rid of that sub query and optimize our database. So we no longer have to do this. But in our Idea component, say on the index one, Library component, or actually we could do it on the model itself, we would have to increment that field. So every time we vote right here, we also would have to do something like this.
do it on the model itself, we would have to increment that field. So every time we vote right here, we also would have to do something like this. So it'd be votesCount plus plus. And the same for removing a vote, we just have to decrement. So that would be on sorry, not here, should be in here. And then decrement would be the same thing, but the opposite way, obviously. So if we can delete it, delete it, and then decrement the count. So yeah, that would be another approach. So like I said, this would optimize the number of queries that we perform. But for most apps, the performance gains are negligible, in my opinion.
