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

Planning Chapter Headings0:30

it starts to get a little overwhelming. So instead, I'd like to add optional chapter headings. So maybe the first three episodes would have a chapter heading of Introduction, and then maybe starting at episode 3 or 4, we'd have a new chapter, Chapter 2, The Basics, and then rinse and repeat as we need to. Alright, I'm going to use TDD to drive out this process. Now I know we'll be working with our Series model here, so let's get started. I'm going to make a new test, a new feature test, called SeriesTest. Alright, and let's take a look there. Alright, what's the first test I need?

Writing Feature Test1:04

Alright, and let's take a look there. Alright, what's the first test I need? Well first, I'm going to pull in the DatabaseTransactions trait, and we'll say, well here you can flush out everything that would be appropriate. I'm starting with a new file, but you might say it shows or it consists of episodes. So yeah, think of a feature test as from the outside in. So you might say, well given I have a Series, and I actually have a little factory, a custom class here to help me with this. So I could say, give me a Series with two Episodes and create that. And I'll import that correctly.

So I could say, give me a series with two episodes and create that. And I'll import that correctly. Okay, so now I could say, well given I visit the page for a Series, and I actually have a method called path for that, I'm going to assert at the very least that I see, well let's start with the title of the Series. Somewhere on the page I should see the title. Okay, let's reformat and give this a run, and it passes because I've already implemented that. Let's do another one now. I'll copy this.

Choosing Data Structure2:08

Let's do another one now. I'll copy this. Next, it may include chapter headings. Now it sounds like I need to set the headings here. So yeah, this is where we have to decide how we want things to work. So as I'm imagining, if I have a series, I want to fetch the chapters. So one option would be to simply make this a text column that we can store and convert to JSON, something like this. Introduction, the basics, you get the idea, right? Another option would be a little more complex, maybe setting up an additional table, a pivot.

So we can set this up fine, but we still don't have the logic that associates a specific episode in the series with a chapter. So for example, episode 1, 2, and 3 belong to this chapter, 4, 5, 6 belong to that chapter. We still haven't done that yet. So if I make a request to the series page, I do want to see these chapters. So we'll do that twice. So again, notice I'm approaching this from the outside in. At some point, I will need to drop down a level, but until then, we're taking a bird's eye view. Okay, now let's knock out...let's see.

eye view. Okay, now let's knock out...let's see. So if I reference my episodes relationship, that will give me a collection of the two episodes we created here. So what I could do is just say, okay, we'll update this for now. We can clean it up later if we need to. But here, I'm going to set a chapter of 1, maybe. And then the next one will have a chapter of 2. So chapter 1 would correspond to introduction. chapter 2 would correspond to the basics.

So chapter 1 would correspond to introduction. Chapter 2 would correspond to the basics. And I think that should be enough to get us started. We have a series that contains chapter headings, as well as episodes that are associated with a chapter. But now before we run this, I do want one more thing. Here's my factory file for a standard Video, as well as a Series. I'm going to make sure that a Series includes chapters. And do note, we don't even have a migration for that yet. And then if we scroll up, a Video itself is associated with a chapter.

Creating Migrations4:42

And do note, we don't even have a migration for that yet. And then if we scroll up, a Video itself is associated with a Chapter. And we'll say, by default, every Video is associated with Chapter 1. Okay, I think we're all set to go here. So I'm going to give this a run, and sure enough, it fails because we haven't created that new migration. We'll do that now. Make me a new migration, and we'll call this AddChaptersToSeries. In the table, I'm actually going to have two tables here, but we'll start with Series. All right, AddChapters.

In the table, I'm actually going to have two tables here, but we'll start with Series. All right, Add Chapters. So we'll start here, and we'll say I want to add a new text column for chapters. So again, this will be a stringified version of our array of chapters. At least that's our first step at it. If we do need something a little more structured, like an extra table, we'll do that. But if I don't have to, I don't want to. But when we drop the column on the down method, we'll get rid of it. Okay, now I could create another migration to add a chapter column to the videos table, but so often, I'll just do it here.

Okay, now I could create another migration to add a chapter column to the videos table, but so often, I'll just do it here. So I'm working with the videos table, and I'm going to add a chapter number here. And that will be an unsigned small integer. Okay, so I'll do the same thing down here. All right, does that make sense? So when I run the migration, my series table will now have a column called Chapters. But we're not going to require that every series has chapters, because I may have an old series that is five episodes, and it doesn't really make sense to be divided into chapters. So I will make that nullable.

old series that is five episodes, and it doesn't really make sense to be divided into chapters. So I will make that nullable. And then for the videos, like we did earlier, we're going to set a default of 1 for every video. So if you override it, it should be Chapter 2, 3, or 4. That's fine. But if you don't do anything at all, it will default to Chapter 1. Okay, so I'm going to migrate this, but I'm also going to set the database connection to testing. And that way, it'll migrate my testing, my SQL database.

Casting Chapters Attribute6:49

to testing. And that way, it'll migrate my testing, my SQL database. All right, let's come back to SeriesTest. So I will still give this a run, and you'll see we get an array to string conversion issue. And that's because, again, we're trying to pass an array to a text column. Here's what we can do. I'll go to my Series model. And if I scroll down, there we go, and we'll say chapters. I want to convert it to, I could do array, json, either works. All right, let's run it again.

I want to convert it to, I could do Array, JSON, either works. All right, let's run it again. And now that error is gone. But we have a new one. If I scroll to the bottom, you'll see, okay, the page does not include the chapter heading. Okay, so that's our next step. And I think we need to drop down a level. So we do have this high-level overview of what we want, but we haven't even figured out how we're going to group these. So what I'm going to do is I have a model-level SeriesTest we can use.

Grouping Episodes by Chapter7:36

out how we're going to group these. So what I'm going to do is I have a model-level series test we can use. And you'll see I have a few simple tests here. Let's do another one. It may include Chapters. Yeah, so notice, you may find situations where you write the exact same test name. But the key is you're testing it at different levels of the system. So in one case, you're testing from the outside in, the way a human would interact with your website. But for this particular case, it's a much more low level.

website. But for this particular case, it's a much more low level. I'm testing at the model level. If I set up a model and I persist it, what will the database look like? Which attribute do I expect? So you're testing different levels of the system. But nonetheless, it will still look somewhat similar. So I could say, with episodes to create. And then here, let's clean up. And I want to use this as a real-time facade.

And then here, let's clean up. And I want to use this as a real-time facade. Okay. So we're going to set up a series here. And just like before, I'm going to specify the chapters. Like that. And actually, in fact, why don't we do three episodes? Okay. So now I could use destructuring here. I could say, like, episodeOne, episodeTwo, episodeThree will be the collection of episodes.

So now I could use destructuring here. I could say, like, episodeOne, episodeTwo, episodeThree will be the collection of episodes we get. Okay. So now, again, manually, I could say, well, update this. And I'm going to set its chapter to one. And then maybe episodeTwo will be chapter one. And then finally, episodeThree will be chapter two. All right. So these guys will belong to the introduction chapter.

All right. So these guys will belong to the introduction chapter. And this one will belong to the basics chapter. So now think about it. If we were to, well, let's say, I do expect there to be two chapters. So maybe if I said Series, Episodes, do we want this relationship automatically grouped by chapter? Or should it just be every video? Or we could even add an extra relationship, like Episodes by chapter. Or we could do it after the fact as a collection.

But yeah, you can imagine if we put everything in chapter one, well, if we group everything according to the chapter, it won't work. And by the way, if you're not familiar with groupBy, this is probably something we should cover. So take a look at this. If we were to get the episodes in the series, we'll get exactly three, as you see there. An array of three episodes. However, you also have the ability to group the collection into nested collections or arrays. So for example, if I said group everything according to the chapter it belongs to, now

arrays. So for example, if I said group everything according to the chapter it belongs to, now notice that you'll get an array where the first item is all of the episodes that belong to chapter1. And in this case, that's two. But if we scroll down, here's the second item. This is all the episodes that belong to chapter2. And there's one item. So groupBy can be heavily useful. And you can use it at the collection level or at the database query level.

So GroupBy can be heavily useful. And you can use it at the collection level or at the database query level. Both will work. Finally, if we want to be a little more specific here, let's grab all of that and extract it to chapters. Okay, so then I could say chapterOne should have a total of two items, and chapterTwo should have a total of one episode. I think that should already work, and it does. So now, yeah, like I said, at this point, if we wanted to test a episodes by chapter relationship, we could tweak the code and then make sure that everything does return.

So now, yeah, like I said, at this point, if we wanted to test a Episode by Chapter relationship, we could tweak the code and then make sure that everything does return green still. But nonetheless, I'm feeling a little more comfortable. Now I know I can create a Series that consists of Chapters, and I can associate each Episode with one of those Chapters. Finally, when I fetch the Episodes for the Series, all I have to do is group them according to their given Chapter. Okay, so now I want to jump back up a level to my feature test. And if I give this a run, of course, it's still going to fail, which means now I need

Rendering Chapters in View11:49

Okay, so now I want to jump back up a level to my feature test. And if I give this a run, of course, it's still going to fail, which means now I need to go to my list of episodes for a series. And here, pretty simple to understand. Iterate over all of the episodes in a series, and for each one, render that episode. So to be clear, what you're seeing here is each one of these. That is an episode item. Here is another episode item. Okay. But yeah, I may have to tweak this a little bit because it is within an unordered list.

Okay. But yeah, I may have to tweak this a little bit because it is within an unordered list. I may change to a simple div. Because what I'm thinking here is we'll have to say, okay, for each series episodes, I could continue. Like I said, we might want to add a helper method to Series. But until then, we're doing it here. So I'm going to say, render it by chapter, and think. That will now give us the chapter number, as well as the episodes associated with that chapter.

That will now give us the chapter number, as well as the episodes associated with that chapter. Then, we could say, for each episode as episode, then render it like we had before. So now think what we've done here. We've split up all of the episodes according to a chapter number. So up here, again, we're putting it in a list item, but this is why we might change to standard divs. But at the very least, we could echo out the chapter number at the top, even within h2. So if you'd like to see this in the browser, let me go ahead and migrate my local database. There we go.

So if you'd like to see this in the browser, let me go ahead and php artisan migrate my local database. There we go. Now let's php artisan tinker for a little bit. You'll see if I switch back to Chrome, let's experiment with this page. So if I scroll down, yes, I do see chapter one. But if I were to say, find me the Series, where the slug is that, all right, I'm going to update the chapters to be, again, just arbitrary, introduction, the basics. Okay, next, we'll say, series, episodes, and maybe the first two episodes are chapter one. But then, give me any of the episodes where the position is greater than two, and we'll

chapter one for episode one and two, and then chapter two for all of the remaining ones. It doesn't look very pretty, but everything is being grouped correctly. Okay, so now, if I return to episodeList, let's quickly make it bold, extra large, I'm not sure, we'll make something nice and pretty. Margin bottom of eight or six, whatever. All right, so now we have the chapterNumber, maybe a colon, and at this point, we would do series, chapters, this is a little clunky, we might want to clean this up. But we need to know which item in that chapter's array to reference. Well, we have the chapterNumber, right? So let's just accommodate for the zero index by subtracting one, and I think that will.

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