04. Reusability with a trait


Right now, if we wanted to use this functionality on another model, we would, of course,
have to go ahead and pretty much just copy and paste everything over to that new model. Now, I've gone ahead and created out a new discussion model, which pretty much is going to work the same way.
We want to log views on there. And I've created that out in the database. And I've also added a view count in there, too. So not only are we going to look at building out
the trait that allows us to share this behavior between two models, we're also going to go ahead and update our sync view count command to use all of the models that we want.
So we can define that in here, run it, and it will update across the board. Okay, let's get started on the trait first of all. So we basically want to take these two functions
and move them over to a trait. Let's go ahead and add this into the models directory under traits, and let's say logs, views, or whatever you want to call it.
Okay, let's go ahead and build this out. So let's add the namespace under app, models, and traits. And let's build this trait out, logs, views. Okay, so we're going to just paste that all into there
and just pull in Redis here. But of course, this is tied down to this specific key. Now, what we can do with a model, a Laravel model or an Eloquent model,
is we can get the table name. So if we just say this get table, let's first of all add this to our article model. So use logs, views, and let's head over
and click on an article. And you can see that we just get the table name. So I think for now, unless you wanted to add in the key that you wanted to use, that's absolutely fine.
So we can replace the name of the key out that we're using in here with another string, and we can add this directly into here. So we can just say this get table and this get ID,
and that's going to be put into there and there. And we'll do the same here as well. So this get table. So that's the first step done.
Let's go over and give this a refresh, and you can see it works in exactly the same way. So let's go over to our discussion model and see if this just works straight away.
So let's say logs, views. Now at the moment, over on the web routes, I've gone ahead and created out a discussion route in here. Let's just do this without a view and say log view.
And then what we can do underneath this is just say discussion, get view count, and without creating a view, we can just see what we're doing.
So let's go over to this discussions route, and we'll grab one of the discussions that are in the database. So let's grab just one, and there we go.
We get a one count on that. When we do it again, of course, we still get one, but what we can do is just swap our IP over, try that again, and we get two views.
So we know that that tray is working between them two models now, nice and easy using the table name to put that into the Redis store.
Now, the only issue is our sync article view count just deals with articles. We want to make this so it does it for all of the models that we've specified.
Now, I'm not going to change the name of this command just to save some time, but of course you'll want this to just be sync view count. Okay, so what are we going to do in here?
Well, a good way to do this would be to, because unfortunately we can't fetch models in our applications with PHP that are using a specific tray. So I'm just going to go and create out a models array
in here with all of the models that we want to use this for. So let's say article and discussion. So we want to define in here which ones we want to sync back to the database.
Okay, so down here now, what we're going to do is collect them up. So let's go ahead and access them models, and then we can go ahead and iterate on them.
Of course, you could just use a standard for each if you wanted to. So each of these, we will get back the class name of the model.
So let's just go ahead and dump that out and let's run that command in here. And yeah, there we go. So we get the first one, article.
Now with this, what we can do is just put all of this stuff inside of there, and that's just going to run for each of their models that we want to update.
But of course we need to change around a couple of things in here as well. Okay, so this one is just going to be model select. So that's going to allow us to start a query,
even though that's a string. The next thing we need to do is change around this key just here. And we can do exactly the same thing with S print F,
and we could use SS. We know the structure of this is views. Now with this, let's bring that model into scope. And the only issue is what we can't do
is something like model get table. That's just not going to work. So what we're going to have to do is new it up and then run get table on this.
So let's new up a model instance. That's not going to be too much trouble. And there we go. And then the second argument for this
is obviously the ID, which we already have because we're iterating through the ID. So that hasn't changed.
Okay, so that's all done. And now when we want to batch update, we want to do exactly the same thing and just new up the model string
that we are iterating over. So iterate over the models, do exactly the same thing that we did before, but of course, query this to the actual model
that we're iterating through. Change over how we grab the count based on the table name and the key that we've given it,
and then go ahead and update that specific model that we're iterating through. Okay, let's take a look at the database. We've got zero, zero for all of these.
And for the articles, we probably have some already stored in here. Oh no, we don't. Okay, so we've got zero across the board.
So let's go and just visit a few articles just to make sure that the accounts are there and they're already there in Redis. So let's go ahead and run this and see this sync up.
Okay, done. So let's go over and give that a refresh. The articles have been synced up nicely and we ran a couple of views
on the discussions that we created. And yeah, sure enough, that first one that we viewed twice with two different IP addresses has been updated as well.
So you can still schedule this command in the same way. Obviously, you're just gonna want to change the name over so it's more generic. And there we go.
That is how we create a trait to handle this logging functionality for multiple models and then update our sync functionality to deal with syncing all of them back to the database.
4 episodes 22 mins


If you need to log unique views in Laravel, you might reach for a database table to track IP addresses or another unique piece of data.

Let's take a look at speeding things up both in performance and complexity by using Redis and the HyperLogLog probabilistic data structure.

Once we're done, we'll set up a period command to sync views back to the database for easy ordering, and then create a trait to share functionality between other models.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.