Rails Tutorial | Building a Blog with Ruby on Rails 6 - Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is up everyone Steven here from tech maker TV in this episode we are going to build out a blogging application in this episode specifically we're gonna focus on the author area or the admin area so what you are going to be using if you're the one writing content I feel like that gets neglected a lot in tutorial so I wanted to start there in the next episode we're gonna focus on the public side so what people will see if they're reading your blog and so on and so forth so what we're gonna build in this episode and this is going to be a pretty long episode is we're gonna build out this page here so you can add new posts once you come in here to a post you can obviously edit the title and description and add a banner image and so on you can unpublish and publish in here and as you can see showing up on the right side of the screen this is reactive so this is all happening right here in the page we can add new paragraphs and images by clicking on these buttons you can edit the content by clicking and then if we want to get out of there we couldn't click cancel you can sort so you can drag and drop and rearrange everything how you want and all of this will save just like that so it's pretty cool so there may be some quirks and some issues and I'm gonna be posting some more episodes like I said so if you've come into this and there's a problem definitely leave a comment in the comment section and I'll try to correct an update and do whatever it needs to be done to kind of get this thing tied together pretty well with all of that said if you like this video definitely give it a thumbs up and subscribe to the channel like I said this is going to be a very long video and I want to know if people actually like this kind of long-form content as opposed to more short like 5 or 10 20 minute videos so if you like this video definitely give it a thumbs up but let's go ahead and dive in and get started with the code to kick things off I just want to start by looking at my rails version or my Ruby version first maybe and so I'm doing two point six point three and then let's check the rails version and so this is six point zero point three point one so if you're watching this sometime in the future and you have a very different version just be aware there may be some minor differences oh that said let's go ahead and create a new app so I'm just gonna say rails new and then I call this simple blog and I'm kind of going off with like a simple theme lately so we're doing another one simple project manager okay so let's go ahead and change down into the app that we just made and we'll just check when we have everything here so let's go ahead and open up this code base so full screen this first thing I want to do is open on my gem file and I've covered a good chunk of what we're gonna do in this video in some other smaller videos so I'm gonna try to move a little bit more quickly than normal through the things we've already covered and give more explanation to newer things I haven't talked about before so I'll link down to a bunch of videos down in the description so if you have questions about anything checked there and then if there's nothing that answers your question leave a comment and I'll get everything that I can but I'm gonna go ahead and comment out this jbuilder because I don't actually want to generate JSON in my scaffolding I'm not building an API or anything like that and I'm gonna go ahead and add a gym here which we did cover for authentication devise and let's go ahead and bundle and we'll see where we get to so let's go ahead and get the devise gem installed so we're gonna fly through setting up essentially the authors section of our application so where you can actually go in create content and manage your content so we're gonna start with all of that and get that fully built out and then we're gonna move on to the front end where somebody would read it so let's go ahead and create a model devise model and I'm going to call it an author but first we need to do rails G devised install and this is going to prompt us to go ahead and take care of a few things in the app so and again I did cover this elsewhere so I'm just going to kind of run through this really fast so we're gonna copy this and change it in our development our B file and I'm just gonna come down here to the bottom device setting just paste that there [Music] then what else we need to do we need to set our route to home index so I'll go ahead and do that for now but we don't actually have a home controller yet so I'm just gonna run a quick command at a moment to set that up but for now let's copy this and put that in our application to HTML by ARB so again like if you're a little confused on what's going on here just read through those instructions they'll kind of tell you what to do and why we're doing it alternatively go check out the other video so then we're gonna go ahead and create our divides views okay so that is basically all of the instructions one thing I want to do before I forget is to go ahead and create that controller so I mean to say rails G controller home and it was expecting an index action so I'm just gonna generate that we may delete that later but I just want to get it there in place for now so that we have it so now if we run our server we can go over to a browser and load this up and we should be looking at the home controller index perfect alright so let's go back over to the terminal I'm gonna go ahead and stop the server and I want to create a model called author so when you log in you're gonna be logging in as an author so we're gonna say rails G devise author and so essentially what this is gonna do is set up a model for us and a bunch of other stuff so that we can actually log in as an author so if we create that you'll see here that we get a new model author and a migration for authors and so on and so forth and it's added devise for authors to our routes so let's go ahead and migrate the database and this will kind of let us get everything set up so we can actually go login so I'm gonna pop over into the code now we're not into the code into the browser rather and if we refresh this and then probably have to refresh that if we go to authors slash sign underscore up we're gonna get ourselves a sign-up page so I can do Stephen at tech maker TV and then enter a password here and so I'm gonna get my alert so everything is working so essentially now in just a couple of minutes we have authentication set up so it's great cool so we need to actually set this up so that we can start doing some stuff so what I want to do is so the the way that I want this to work is we're gonna have posts which is basically a blog post and instead of just having one big text body inside of one big like you know WYSIWYG editor or something like that what I'm gonna do is create it so that you have a post which has many elements and so you can like drag and drop and sort these things so you can have like some text and then an image and then a video embed and all this kind of stuff and then you can organize it it's maybe not the you know perfect idea or whatever but it's something I'm kind of interested to do and I think that it'll be pretty interesting for you and it's gonna look really good when we're done so let's go ahead and set this up so I'm gonna create a scaffold here again I have a recent video on what the heck scaffolds are so I'll link down to that if you want to see it so I'm gonna create a scaffold and I'm just gonna call it post and it's gonna have a handful of things so first of all we're gonna give it a title which the default if you don't specify a string so we're gonna make that a string I'm gonna give it a description which is going to be text I want to have a published true or false so it's either published or not which is a boolean I'm gonna add a published at if I can think I didn't spell published right there wrapped around I finally published she's gonna be a date-time so the timestamp and what else I need to have it reference the author so it's going to say author references which is essentially going to generate an author ID and some indexes and I think that's good enough for now so I'll just hit enter and it's gonna run some stuff here and I'm just gonna run rails DB migrate and once we get this up we will go check it out in the browser by running our server so once that's running we'll jump back over here and we'll go to slash posts and now you can see here that we can create posts and it's kind of got a few problems in here because for example it's saying we should actually type in the author this published at and all this kind of stuff is very very weird we're gonna change all this up so don't worry about it but you can actually play around with it if you want to and I see how it all works but let's go see what this did and the code for us so let's open up the post controller and you can see here if you're familiar with scaffolds that this doesn't have all the sort of response hoodoo format stuff and that's because I commented out J builder I think if you aren't gonna actually use this as some kind of JSON API that's a good thing to basically comment out at the beginning because otherwise you're going to end up with a bunch of junk you don't want but anyway so this is pretty like neat and good to go so now that that's setup I want to modify a few things a little bit so that we can essentially add some security here so what I want to do is I'm gonna close all of this and then open up my routes and start there so we have this resources post that was added and what I want to do is sculpt this so that you'll see what it does in a minute so we'll say scope module authors do and then we'll push that up in there and now if we go to our post path and refresh it's gonna give us an error and say uninitialized content authors so what this is trying to do is say use instead of saying like post controller it's wanting to look at authors post controller and so what I want to do is sort of segment where the code lives a little bit inside of my controllers here so I'm going to create a new folder and I'm just gonna call this authors and I'm gonna drag the posts over in there and then I'm going to open that up and go to the top and say module authors and then I'm going to tab this in and bump it up in there now let's go back and refresh and now what's going to tell me is that we're missing a folder for authors for the views so if we go back down into our views folder it will create a new folder called call the authors here and then we'll drag the posts over in there so I think it should actually I'll be working as it was again now okay and I'll go ahead and just like create something just to kind of make sure everything is working it looks like it's all good to go okay cool so now what I want to do is go another step further instead of just having this application controller which is this is inheriting from I'm gonna set up an author's controller now I need to do this in the top-level authors controller and in here what I'm gonna do is create a class which is authors controller and it's going to hair it from application controller and what I want to do in here is just before we do anything I want to authenticate the admin so I can do say before action authenticate at author that's the word we used right I've indicated author and then in the post controller I'm going to inherit from the authors controller like that and now if I go back over here and refresh it's fine but if I copy this and I open an incognito window tell me I need to sign up before signing in before I can continue so that's what we want that gets at least part of our security in place so that you actually have to be logged in before you can do anything with its content okay so then the very last thing I want to do with this for now is specified the layout file and I want it to be authors so if i refresh over here now it's gonna tell me that that layout file is missing and so the reason I'm doing that is because I'm planning to have pretty different look and feel for if you're logged in as an author versus if you're looking at the just regular website so I'm gonna create a new file and from now well I'm gonna call it authors that HTML about yarby and then for now what I'm gonna do is just copy application and we'll put that there so this gives us the ability to do things like have different resources that we want to use for authors versus like I guess we can use application for the regular views or whatever so it might have different fonts we can change the fonts and the styling all this kind of stuff completely independently so it's a little bit like we're running two front ends in parallel or something like that it's not exactly that but that's a reasonable explanation for what we're doing the next thing that I want to do is actually set up bootstrap and I'm just gonna grab the CSS because I'm not planning at least right now to do anything with the with the JavaScript so I'm just gonna go and search bootstraps again and I just want the CSS here and we'll go ahead and grab this HTML here it won't pop back over to our authors and put this up here at the top save that and then let's go back over to our close this cuz we don't need it let's refresh this so now you can see that the Styles changed so we have bootstrap running and I'm gonna go ahead and jump up to my assets directory and and delete this scaffold CSS because we don't want that to be interfering with everything okay so now let's go and close everything and open up our posts index so what I want to do is actually I need to create some posts and so I'm gonna go ahead and fix the forum for the post because it's all kind of messed up right now so what I want to do is take away these published related fields and I'm gonna take away the author related fields and that's probably good in my post controller we're actually going to set up and some other code later for actually running the publishing process so what I need to do is in here when I see index anywhere where I see post I'm basically gonna put current author dot posts so first of all sorry I'm kind of working my way through this backwards right now so on author we need to say has many posts and this is going to provide us a post method which we can call on the author to retrieve the posts that belong to them so on sent post I'm gonna say current author dot posts and that will make this is essentially scoping so that if we're gonna look anything up we're sure that the post does in fact belong to the author we don't want people to be able to edit other people's posts so that basically sets us up well for destroy update and well show edit update and destroy so what we want to do here is just say current actually index should we just current author posts and then oops sorry make sure I copied that so then here for new will say current author dot post build and then same thing here so current author dot post dot build for the post params and then we save it redirect so now everything is scoped to this author so we don't need to pass the author in from the front end which wasn't a good idea anyway it's just because of the way that the scaffold set it up and so we don't want to have the author or the author ID be able to be pushed in or or sent in and I'm gonna go ahead and take away the published and publish that as well so the only thing that you can really edit or create with our the title and description so let's go see what our posts look like now so we'll create a new post title testing this and testing this thing out so now we can create a post go back now we see on our index page we have a post test number to testing it out again okay so that's good to go so now I have a couple of things so now let's actually work on styling this page so if we pop back over to the index you'll see here that we have all of this table stuff down here so I'm gonna go ahead and just well we have this notice in the application layout I'm gonna go ahead and get rid of that because that'll give us double notices for now it'll fix that up later the first thing I want to do is essentially say how can I do this so I'm going to add a container here in an actual fact let me think for just a second do we want to contain everything all the time in here I think so let's go to our authors layout and what I'm gonna do is just inside the body I'm gonna say there's a div of container and then I'm gonna bump all of this up into it and I'm gonna actually give this body a class of BG Lite which is going to give us a light gray background color and then what I want to do in here is start with I guess we want to just say H I'm gonna make it an H for posts this and what I want to do in here is say that this is so what I want to have is on the left side screen it's gonna say post on the right side of the screen there's gonna be a button for new posts so I'm gonna say class equals D flex which is display flex and bootstrap and then justify content between and in order for this to make sense the post text actually has to be in its own element and then so I'm going to paste this here then when I come down here to the bottom of the screen and get this link to new post and it will paste this just here and then I'm gonna give this a class BTN BTN primary and let's go see what this looks like so now we have posts and then we have a button for creating a new post so we don't need this h1 and now instead of setting up a table I actually want to put together basically a card for each post I'm also gonna give this an in beef for maybe before so that's margin-bottom for I'm not sure what for is looks like REM or something but basically bootstrap has this M they have several things like utility classes now where you can do M - 4 which is like a margin 4 and B 4 is bottom they have TL and R for top left and right they're the same thing for padding and a handful of other things so what I want to do though is say at posts that each do post and again that post is coming from our post controller here so we have all of our posts by this author here so we're going to loop through each of those posts and for each one I want to create a new actually I want to do this I wanna say link to do link to post due and then I want to have a card in here so what this is gonna do is make the entire card into a link so our card card body and then I'm gonna have a P tag let's make it an H five tag with a class of card title and this will be post that title and then let's see here what else do we have so what I actually want to do here is kind of the same thing I think well let's just get this going with kind of the basics and then we'll do post description so what I'm actually gonna do is have a little badge somewhere on here saying whether or not this has been published yet I'm gonna have an image that you can upload so we'll get to that in just a minute but I don't really want the rest of this on here at all so let's just get this and see what this looks like so if i refresh here nothing so I didn't do something I didn't print out the link here so that should be good the one thing I wanted to do also is make sure this has a MB on it so that they're spacing so let's go check out the browser now so now if we click on anywhere on here it's taken us into the post so that's kind of cool okay so let's make a couple of quick changes here and then let's work on the edit page so on this post I'm gonna give this a class of text-decoration:none and then on the h5 I'm gonna give it a class of text dark and then the P tag will do a class of text secondary so again I make heavy use of these bootstrap classes I think it's quite nice what they've done let's give this an MB of one maybe and let's see what this all looks like so that looks pretty good maybe I want to give the text of the P Tagget mb 0 is that a thing we can do so that tightens this up pretty nicely okay cool so I'm liking this I'm gonna go ahead and mean we'll make this a lot better don't worry it's pretty simple right now but then I'm here I want to go ahead and get this sorted out in actual fact I don't think we really need a show page when you click on this I think you should just go to edit I think that's it actually so I'm gonna make this link to edit post path and you'll see what I mean in a minute so let's go back here and refresh so now there's really just those two things we can still get to the show page if we click here but this page isn't gonna it's gonna end up being kind of useless for us so I'm actually gonna remove the view entirely and I'm gonna remove the controller action okay so if we go into our post controller and we're just gonna get rid of this show so that's it and I don't need this here anymore either so now if we click here if we click this I should get an error so I'm gonna go and modify this edit page now so we'll go to edit and let's see what we want to do in here so the first thing I want to do is create a row so I'm gonna make a two column kind of structure here so I'm gonna make a first column which is gonna be like maybe three columns wide again bootstrap is I'm using bootstrap here so kind of to familiarize yourself with their grid structure but inside of here I'm gonna just say h4 and then we'll say editing post actually I wanna make a card do another card body kick this up inside there say that's the card title and we might make that in h5 let's leave at age 4 for now I don't need that anymore this I'm gonna put at the very top and give it a class of BTN BTN secondary maybe and we don't want to show and then we do want the form inside of our card body okay so if i refresh this it's kind of what we're looking for but not quite so I'm gonna make this have MB 3 and then in my form which I need to come in here and fix each one of these text or this text field in this text area I'm gonna give this a class of form control so just copy that and paste that there and then at the button I want to give it a class of BTN and primary so let's refresh all this and see what we got pretty good I want to change this let's change the field I think in bootstrap we need to call this form group and I don't know why my editor is not letting me do multiple things at once so that's form group now you can see that's kind of I did something I need to add a class of BTN okay and I'm actually going to add another class here BTN block which is gonna make it expand to take up the entire width of whatever it's contained in so now this looks better for sure so what we need to do now is actually add something where we can click a button right here that will add elements below okay so this is gonna start to kind of get a little more complicated pretty quickly so hopefully you're listening up to this point so let's jump back over to our terminal and we will run a couple things here so I need to create something that is going to essentially hold the content and so what I'm gonna do is create something right it's gonna be called an element and it's going to belong to the post so we could call the post element but I get tired of typing post-op post elements so I'm just gonna call an element if this was a bigger application you'd be need to be more specific probably but it's fine for our purposes so I'm gonna create a model actually let's give it a scaffold and we're gonna call it element and it's going to have a element type which is going to be a string which you could leave that off sets a default it's going to have content which is going to be text it's going to reference the post and let me think if there's anything else this needs to have I think this might be it needs to have a position which is going to be an integer so we won't be making immediate use of the position but it's going to be important in just a little while I think that's it the one thing I do want to do here is skip template engine I believe is the correct flag I don't want to actually have any front-end for this I just want the controller actions and model so let's see what this does and then we'll run our migrations and we'll go check this out so if we look at our views down here we don't have any front-end for our elements now what we need to do though is actually drop the elements into the authors area we'll need to do what we did before where we say module authors and we'll move all this up and then here we'll change this to be authors controller so that kind of puts our baseline security there where you can't do anything to an element unless you're logged in so let's see here so what else we need to look at the routes because we'll need to bump the elements down into here an actual fact those are going to be nested so now let's just see what this does let's go check out our routes over here so we'll say rails routes and then we'll do grab element and this is going to show us what the routes look like for this so you can see here we have post elements and then it's slash post / post ID slash elements so the elements are nested inside of the post so you have to have a post ID to really do anything with an element so what we want to be able to do is click a button right here and create an element and let's go and see how we can get that to happen so we're rendering the form here in our Co L and III I want to create a new one Co l and the time and right inside of here I'm going to put a form for our our elements and I'm gonna make sure to give it a type of text right now or paragraph maybe so we're gonna have different element types so I'm planning to have a paragraph which is going to be rich text I'm gonna have a video embed I'm gonna have an image at least those three things I think that's probably it at least those three things so let's go ahead and try this so we'll say form with model and then we'll need to give it the post and a say LM text element maybe and then we'll say do ends here and we don't have a text element so if we go to our post controller eggs need to say at text not on the index page on the edit page so we'll say at text element equals at post dot elements dot build and then we'll say element type is paragraph and actually I'm gonna go ahead and call that paragraph as an instance variable so post elements so does the post actually have any elements nope so we need to say has many elements okay so now let's jump back into our front-end where was that edit so we're gonna say at post at paragraph and let's just see if we can get this so I need to say do form so now let's just do a quick how can we do this see so I'll just do form dot submit let's just see if this even works see if this breaks our page I need to start my server okay let's go see if our page loads so now I have this create element button here before we keep going I want to go ahead and delete the scaffold CSS that was generated again so I'll just get rid of that and refresh and now that should kind of line back up right let's click this button and see what happens so look like nothing happened both go check our server so it looks like we started a post and when I get this action controller parameter missing Quran is missing element so let's see what's going on with that so if we jump back over into the code we pull up our posts now our elements controller so you can see that what we're trying to do first of all we haven't done anything with regard to finding our post yet so let's go ahead and do that so we'll say well create a new method called set post also a post equals current authored posts got find and then that's gonna be params post ID that's gonna be on every single action so we'll set post all the time here because it's completely nested if you will recall then on our set element here we'll say at post elements that find index I don't believe we need an index I need any we really don't need any of these we're not gonna use those at all and we don't need these then so we really just want create update and destroy and here what I want to do is say at post elements dot build and then we'll say if elements save will redirect you at post and I don't want to notice so in actual fact we don't really have a new page that we're going to be redirecting to so what I would probably do here actually say notice well let's see here so we can redirect to posts with a notice and a notice was gonna just basically say or should say element we could say at post dot errors that full messages join like that maybe something like that so this gives me an idea because we actually need a validation on our element but before we get to that I want to get rid of the post ID in the position those are not things are gonna pass in okay so let's go over to our post actually that should be element that errors so let's go to our element and I want to do let's do this will say validates element type and then we want to do an inclusion and then we just want to say n and so I want the element sides to either be a paragraph or image or video embed for now we may add to this okay so let's go back over to our browser let's refresh now if I try to create without it could not find show for post them on the edit page okay that makes sense so what I want to say is right here will say edit post pass like that and then we'll go ahead and copy this and replace the variable here so in any case we want to redirect to the Edit post path you know what we could actually do is well let's leave that actually now let's go ahead and refactor this a little bit so what we could say cuz this is actually an interesting little side note here whenever you see this sort of thing really what's the difference between these and so what what the if is actually controlling is just the notice so I want to have the if just control that notice so if element dot save so will say unless well if element dot save notice equals nil else notice equals this like that and then down here should be able to say notice notice so that's kind of a little bit cleaner so now basically we can we have inside of the conditional this thing that the conditional is actually sort of handling so I like that better we'll see if it works just a second I'm not sure if we can pass the nil to notice like that but I assume it's fine okay so let's give this a shot so if we come back here and we click create element so you can see here we get this message element type is not included in the list so what I'm gonna do and I'm actually going to need the element params again what I'm gonna do is put that just got myself lost here edit so I need to have a form dot hidden field and I'm gonna say this hidden field is for the element type and I'm gonna say the value is paragraph okay so let's refresh this and create element so no errors on page this time and you can see here that we have a post and it looks like everything was okay alright so let's go back to our code for just a second so I want to move this link to back down just inside of that column and I want to make this form submit say for now I'm just gonna make it's a paragraph paragraph and I'm gonna give it a class of BTN BTN primary well change this up a little bit later when we start getting to other sorts developments but now this is gonna pop up here actually this didn't move up what happened was just back move down but just visually this moved up so what I want to do is on our edit page here so under this I want to say talk me do this at post elements that each do element okay and then I want to actually set up a form for the element we'll change this once we get to will change this once we get to images and stuff but for now we want to basically have a text field for our rich text content so what I'm gonna do is say text area and that should be content I don't want to value and actually I'm not even gonna put a class on it for now and then this I'm gonna say save let's see what this looks like so we have to one of these isn't actually saved to the database and it's because when we initialize this in the post controller we're saying current authors post out-build so what we need to do is to check before we display that because what this does is this basically makes it so that current authors dot post has an extra item in there and it's not safe to the database so it's this like sort of pre-baked post that's not quite ready to save so what we can do to prevent seeing that is actually say if element dot persisted so in otherwise in other words is it safe to the database so now we should only have the one and I'm going to go ahead and I need to add some padding here so I'm gonna say where should I put this I think I need to put it in here at HTML class you know what I'm gonna put a div around this thing so I don't have to like modify that form classes at the moment so we'll say div and b3 alright let's see what that looks like so now that lines up with this I'm gonna fix this in just a minute but actually we're not gonna be using this this kind of text box we're gonna have a rich text editor that we're gonna use well let's just test this out and see what happens if we save it and if i refresh you can see that that's saving now let me actually come over here to the elements controller and say if element dot so you can't create it without the element type and there are no other validations right now so I'm just gonna say element dot update and I want to redirect to that may have actually not updated cuz there should have been a notice when a read write to you element dot post and I want to make that the Edit post path like that so let's see what happened update elements yeah I did update obviously we looked at it but there was an undefined method element URL so it just kind of froze and we didn't actually see the message I guess so let's try this out again so now if we were afresh we're still seeing the same thing okay so that looks I mean doesn't look good but it works so to actually make this into rich text what I want to do is actually go over to my terminal and we're gonna do the following I'm going to use something called action text that's I think it was new in rails 5 will say rails action text install and this is gonna create a handful of things for us I think it's going to create a table for some background jobs it's gonna create something else to store the actual rich text in so you can see down here we got these two new migrations and I actually realized that I don't need a content column on my element so I'm going to remove that so I'm gonna create a migration for remove content from elements so we're gonna go over to the database really click the database area I'm going to look in my migrations and I'm gonna say and here remove column and I'm gonna say I need to name the table so elements and then content is the name of the attribute I want to remove so let's run this migration rails DB migrate and this should trigger three different things at least okay so this should be pretty simple now so if we go back over to our element class what I want to say and here is has rich text and then it's gonna take an argument of content and then back in our view over here instead of textarea we're just gonna say rich text area and I don't need this class I was messing around earlier so we'll take that away so let's just quickly review this feldman persisted rich text area okay so let's refresh this and see what we get okay I mean you restart my server that would help okay so let's try this so now you can see here that we have you know basically we can do different things here you make it bigger so on and so forth I'm actually not sure what that does to make that like like what size that ends up being so if we save that let's check in the Turner really quick if we run over here and we say rails see let's look up I think that's element it's probably the only element right so element dot first and if we do that and then we say dot content let's see what that content dot body so I've got an action text object public methods all just kind of curious about what this is going to look like to HTML maybe to HTML so we have an h1 tag in here so we can make that into an h1 tag by basically clicking on that T thing so it's kind of strange what that's going to do is it means that we're only going to essentially have an h1 tag available if you look at this because you can see that basically either have a regular text where we have big text I don't know how I feel about that but we'll leave it alone for now okay so what I want to do is first of all I want to style this up a little bit once we get a few paragraphs on the page but I would I would like to see is if we click into this what I want to see is that there's just regular text and if we click on it becomes a form and so I want to style this up a little bit better in that direction so in here first of all but I just noticed that there needs to be a little bit of a margin here from the button in the form so I'm going to give this an MT 3 and I want to put this entire this entire area inside of a card so what we'll do is say div card div card body and now let's just tab this stuff in and put it inside of that card ok so then and if you see me like cutting and pasting I'm trying to figure out a few things with my text editor right now I'm gonna end up just uninstalling and reinstalling it probably because a syntax highlighting and screwed up right now but anyway that's not really my forte is messing with that stuff but anyway I'll get to it eventually so let's see what this does for us so if we come over here and refresh now this is kind of in a little section if I add another one and we see that lining up like that so what I want to do is add underneath each element so first off let's put each one in like its own div so we'll say div and then just give that an MB 3 and let's paste that back here ok let's see what that looks like now that's kind of laid out a little bit better I'm gonna give this a PT 4 kind of knock that down maybe 5 let's see what that looks like okay so that looks a little bit better so what we need to do is inside of here I'm gonna create a div and I'm going to say paragraph content and then here I'm going to say paragraph form and again Tabitha and move it up here and then right here inside this paragraph content div I'm gonna just say element content let's see what this looks like okay so now you can see that we have our content printing out there we can save it and update it and this is obviously rich text that's being printed out so action text makes that really easy and automatic so it's just whatever you see here is what's gonna appear there so what I want to do is make it so that when I click on the content the it swaps in for the form and when I click out the the content comes back and so I did this in a recent episode and I'm gonna steal some code really quick and then we'll modify it because what we're doing is not exactly the same but it's really similar so I'm just gonna copy this and jump back over here and then we'll go to our application JSO and I'll link to the video in the description but we just want to paste that in here so what we're doing is saying on turbo links loads this is kind of standard it's sort of like when the page is ready we're adding an event listener click and so we want to listen for if the click occurred inside a paragraph content we want to add the class d nun which is display:none in bootstrap and we want to remove the class d9 from the next sibling so we need to add a D nun class here so we're saying display:none on the paragraph form by default and then there's a cancel and then we're saying paragraph so I should make this paragraph form so basically we need a button with a class of cancel and when you click that we find the paragraph form we advocate d9 and then we go to the previous sibling and remove the demon so we need inside of here we need an a tag with a class equals cancel and I'll go ahead and give it a class with BTN BTN secondary and then we'll just say cancel and let's go see what this does for us so if we refresh we should just see this and if we click it goes back to what it was so this is great what I want to do I also mess up my button here so let me make sure I do this right secondary let's go try that again and see what happens so that needs to be lined up better is there a in B there's so what I'm gonna do here is actually do a div MT 3 and take the MT 3 off the button and then we'll get these two and bump those up together now let's try this so now I have save and cancel so this is pretty cool so you'll remember that there's actually a second one of these things down here somewhere I think I think we added a blank one so what I would like to say is if element that content dot present show that else will just print out a click to add content like that let's go see what this looks like so click that content and now I've got that so what I don't really care for here well that was kind of interesting I got on both active when I clicked cancel they both went away that's kind of funny don't know how I feel about that maybe it's fine what I would also like to do is just add a little bit of custom styling for this paragraph this whole section so first of all let's make this P 3 let's go see what that looks like so just kind of pad that in now this isn't our actual blog post page is a content management page so it's not going to be styled like this on the public front end it's going a little less concerned with how all of this looks we'll worry about the text spacing and stuff like is this to me is a little bit too much of a gap just for having a line break and the layout here is a bit strange so we'll come back to that but for now I think it's okay what I want to do is say let's make this a paragraph this whole thing is a paragraph right here I want to add some custom styles which we haven't done any of yet so first of all let's go to our author's HTML to make this a style sheet pack tag which is gonna pull the styles from web Packer then we'll come down into our JavaScript directory inside of our app folder it will create a new folder called style sheets and I'm gonna create a new one in here called application s CSS in here I'm going to add import base like this and I'm gonna create a new file this is a lot of old files and I apologize that's just how it is so I'll set up a file called base inside of base I always do this just to make sure I'm always doing a little sanity checks so I like to do something really outrageous like background color black important so we can't miss it and then in application what I would like to do is say import style sheets slash application I think that's it let's give this a shot really quick so let's refresh see what happens if it loads our background color no it did not elements body okay well it did give my style I just messed up because this one there goes so the BG light already hasn't importance of bootstraps giving us an important and it overrode our important so but it's in there okay so no worries we're all good so in my base here let's come back to edit so paragraph so this paragraph what I would like to do so dot paragraph and you know I probably want to nest this somewhere so let's do this just really quick and this is kind of a minor thing for the moment but it might not be soon so inside of this body I'm gonna give this a class of authors because this is our authors layout so what I want to do is make sure that what I'm editing here isn't gonna break something later like on the public side in particular so authors paragraph and then in here I'm just gonna say and hover background color and what is the what's the bootstrap background color so BG light if let's copy this I don't want the important but I want the hex code it's probably a way to do this with a variable and I don't know if that would work because we actually just brought that in from a CDN so I'm just gonna get that color and let's see what this does so now we can see these things so let's actually when we hover let's make the cursor a pointer and let's make their a transition background color 0.5 seconds ease and let's go back to the paragraph so we have n b3 I make this M before so it's a little bit more spread out even so when I only hover it's almost not dark enough come it's very faint Oh Nelly that got weird what happened so it's like it got it messed up our maybe I need to actually import this first before action text let's do refresh here see what happens huh so we messed up action text styling somehow which is pretty strange okay I'm not sure what to do about this we'll fix this but I have to pause and figure out why that broke so it looks like when we change that to the JavaScript pack tag we missed a couple of things so up here the command to generate action text automatically brought this in which is sort of this is a little bit hidden but this is one thing this required tricks this tricks and then we also have all of this stuff so I'm gonna go ahead and copy this and then in my let's go back down here create a new a new file I guess just create a file call to action text is CSS paste that in above base will at imports action text and I'm going to go ahead and give that the relative path here and then we need to import so over here in where was that action text up here so we need to require this but we did it a bit differently in sass than you do in regular in the CSS stuff so what I'm gonna do is add imports like that so let's save all this and let's go refresh and see what we got okay so you can see that formatted properly now okay so this is working now so the next thing I want to do is add the ability to create images up here so let's go ahead and close up a bunch of this stuff and then open up our edit page or post so in here right now we're saying if element is persisted show this stuff what I would also like to do is say well am i right there so inside of here we'll say if if element dot paragraph then we'll have all of our paragraphs stuff that we have and we'll say else if element dot image we're gonna have some other stuff now we obviously don't have those what we need to do is go over to element we don't have those methods that is so we'll say a paragraph question mark and then we'll say element type is a paragraph and then we'll do the same for image okay so now what we want to do is up here we have this form for so on and so forth we want to make this we want to make another one and it's going to be formed for paragraph and image and it's gonna say image and the hidden field is going to be for an image now we don't have an image yet so we need to go over here and say post controller I think is what it is and in here we're gonna say image and image now it's possible that we only need one element here and that might actually be right so I'll try that a little bit later with just the image or just the we could have something that's like this we could have element and then we could get rid of that let's get rid of that let's just try it like that let's see if that works so then we have post element here because essentially these forms go to the same place the only thing that's varying is this this hidden field and I'm gonna make both of these a BTN dark because we don't want a bunch of blue buttons across the top of the page let's refresh this and see what happens the only thing I would like to do let's see how can we do this we can say HTML class maybe like float:left on this one and then mr2 okay so let's try to add an image and see what happens so if I click image it should basically add one so we can check the server and see the logs here so it went ahead and posted but nothing is showing up and that makes sense because we don't actually have anything registered to print out down here so I could actually just say image and now I should see the text image print out it's what we really want to do is actually have our form so we'll copy this form and instead of saying rich text area I want to actually look for oh we want to add a file field and we want to look for an image so we need to make a couple of small changes to the elements so on the elements controller we want to allow an image to come through and then we want to open up our what is it it's the element dot RB so up here it says has rich content we can actually do the following so we can say has one attached image and the reason this work is because when we created our rich text it actually went ahead and set up active storage as well and active storage helps us with file management so it makes it really really really easy for us to actually add file uploads and stuff so this has to work a little bit differently on a production setting but this should work fine for localhost so let's refresh this and give this a try so of course I have my cancel button which I don't need humble it's to the file I need to like grab something like this this will save it let's go look at our server and see what the logs were so we have an update right here and so on and so forth and it doesn't actually print anything out different because what we haven't told it to so and what we want to do is say first of all let's indent this so what we can say is if element dot image dot present let's actually print out the image so we'll say image tag element dot image hopefully that works just like that if not we'll fix it in a second else and then we have our form here okay so let's give this a try in the browser so look at that now that image is apparently gigantic so let's go ahead and style that just slightly so gonna do what I did above and create a div image so I'm going to say div image and I'm just gonna copy or cut all this and paste it in there and then back over in our base CSS so inside of authors I'm gonna have that image max width a hundred percent so this should I kind of squeeze this in here nope what did I do wrong oh it's because I need to actually grab the image tag so the image tag max width is a hundred percent now let's try this let's see what happens okay so now you can see that's fitting into the page so now we have the ability to add rich text and we have the ability to add paragraphs here one thing we need to be able to do is delete everything so with images I don't really care about changing the image because frankly you can just delete it and upload a new one and with the text you can already edit and so on so it just need deletes for all of these items so let's start with the paragraphs so if we go up to where we have the forum here what I want to do is actually make this a D flex and do the same thing justify content between and then I'm gonna make a div here which is gonna live on the left side of the screen and then I'm gonna make another basically a link to delete and that's going to go to the post element path and then we'll give it the add post and the element and then we'll say that it's method delete class BTN bTW in danger let's go see what this looks like actually we need to do one of those thing which is data confirm are you sure it's always good to prompt before you do a delete on something like this so let's click in here not only assume we have a delete over here on the right side screen if we click in here can click that are you sure and we didn't actually update that on the elements controller to redirect to the right place so let's go back over there and we want to just redirect to that element dot post and I keep doing this wrong so let's copy that so we're redirecting to the edit page let's go back and refresh so now we can go ahead and delete this now we just have our image if we add a paragraph we'll get the new paragraph down here so that's looking pretty good I need to add a little spacing around this image and actually one thing I think I'm gonna do I'm sorry I'm kind of like building this out on the fly I have a pretty decent idea of what I wanted to look like but not a hundred percent so I'm actually kind of working it out as I go so we're gonna add a little bit of styling here this image what I want to happen is on the image I want to text-align:center and then I want the max width to actually be something like eighty percent so that doesn't take up so much space let's check this out so what I tried to do there is make the image a little smaller and centered and then give it a little spacing between that and the text elements around it okay so this is uh this is actually working pretty well what I need to have is a way to delete this image so what I think I'm gonna do is put something like I guess I'm just gonna put a little delete button just below it on the right maybe maybe that's the right move but what we can actually do is just copy this exactly and then down here we'll just have a link to delete I'm gonna add Mt two maybe then we'll say float:right that might not work together let's see what this looks like that's not what I wanted MT - where did that go is that doing some kind of oh it's because both of those are in line items I believe so if I put that and it divs bump that up like that let's see what that looks like so now that's gonna Center it and I want to actually float it to the right I'll see if that works huh it's not terrible it's kind of weird it's not terrible let's see if it works okay so cool now this is pretty much hooked up so we're going to do another pass at this once we get once we get like a little further along because I don't like the way that looks but I can live with it for the moment what might be nice is if there was actually an icon like hovering right here like an X and these are actually we're going to turn these into icons in just a little bit but I want to add a few other things before we get there so let's jump back to the code and I'm gonna open up that edit page again and I'm gonna open up the form so we added a I don't think we added anything to the let me check the schema really quick so we have all of our active storage stuff we have elements post so I actually want to add an image to the post and we're gonna call it the header image and so what's nice about this active storage is we can just come in here without doing anything into the actual post class really you can just say has one attached and we can call it like header header image like this and what we can do when we have that is we can come down here under our we can come down to our form for the post and give it a header image file field like this and I'm gonna do I'm actually gonna reuse my oh no sorry I just kind of figure it out loud so if if there is an image so if what's the object here it's post header image dot presence will actually print out an image tag header image that should be a host header image and I'm gonna give it a width of a hundred percent right here I think that will work okay so let's refresh this undefined method field field it's been a long day so file field okay so now it's going to say we'll get this weird like I guess it's because I'm in a form group it's trying to make this little border around it not gonna worry with it too much I need to get some like smaller images maybe I had something like on my desktop show cannot be found for post controllers so let's go to the post controller and right now we did not fix these so we need to make this edit post path and again I think I don't want to notice here and I'm gonna do the same thing there so rad choose a file again and click on this thing so it doesn't look like it worked maybe it was post a header image oh okay mess that up so on a post controller now we need to allow the header image parameter to come through so we have to permit that explicitly so that in our where was that in the forum so we have a file field for header image so anytime you have some kind of form attribute you trying to pass through you have to explicitly allow it so try this one more time so we'll choose image we'll grab this okay and so now we see our image printing out here below and I want to go ahead and make a little although see a div classes MT one okay and trying to decide if I want to say something like small current image maybe like that yeah I think that looks great so now that I have a header image I actually want to display it out of here and the way that I want to go about doing that is first of all I always like to close down the files as I'm kind of switching ideas that I'm working on just helps me stay focused so I'm gonna open up the author's post index here and what I want to do I may change up how I'm doing this so be forewarned but what we could do is say something like div co L in d2 and then div Co L md-10 and then in here I could do something where I say like div class equals header image so on this I'm gonna create a class of post card then we'll have a header image and then in here I'm going to say style equals background-image:url and then I'm gonna give it the post dot post a header image I think that will work like that so in our base let's go down here to post card and let's see we want to say post card header image width is a hundred percent and the height I don't let's call like a hundred pixels or something and let's refresh this and see what yet so we're not getting anything I suspect we actually have to call URL on there so let me actually throw a header image dot let's see so after a little bit of googling it looks like I need to do this URL for post dot header image and I'm personally not super crazy about that style there but you know maybe it's fine undefined method to model delegated to attachment but attachment is nil okay so what I need to do is say if post a header image dot present okay so otherwise just leave it alone okay so we got that going on I'm gonna move those up into there okay so that should have done something different oh I need a row here so this is a bootstrap thing but you have to have a row if you want the columns to split up properly I think okay that's getting a little bit closer to what I'm thinking obviously I want the image to be styled a bit differently so I'm gonna go over to my header image background size cover background position Center let's see what this looks like okay so this is definitely getting closer to what I'm imagining here let's just see if we can make that a little bit problem is this thing's gonna vary as we as we squeeze things in so like if I let's open up our developer developer tools here and turn this on to responsive so you can see that well I don't actually have my my meta tag to set the initial width done properly but you can see as we go through the sizes that that kind of gets a little bit weird but I'm gonna leave it alone for the moment so the next thing I want to do is set up something where we have a button down here to publish or unpublish a post and then we're going to set up the logic to make that work so if we go in here to our edit page just under render form outside of this I'm going to create a new div and I'm gonna make it the card footer and then basically what I want to do is say if at post op published which we get this published with a question mark method automatically when we had a bull into the database with active record so if the post is published let's make it an a tag with a class of BTN BTN danger maybe and we'll say unpublish and then otherwise you know let's make that a BTN I don't want to have like bright red all over the place so secondary and then let's make this one dark for publish let's go see what that looks like and I'm gonna make those both a BTN block so they take up the entire bottom so that looks okay so what I want to use to actually do the publishing and unpublishing is a tool called stimulus reflex which I've been playing around with and pretty excited about lately it might be kind of overkill for this project but that's okay it'll be fun so let's just go with it so what we need to do is run first of all we need a bundle so stop our server bundle ad stimulus reflux and this will rerun bundle install and add that Jim to our Jim file so once that's done the next thing we need to do is a rails stimulus reflux : install and this is going to set up a few things for us so once that finishes we should be able to start creating what's called reflexes so I'm gonna run this I'm gonna say rails G stimulus reflex and I'm gonna create a reflex called publish and actually let's let's actually rename it so we should be able to do rails D which is the opposite of G so it would generate and destroy so I'm gonna call this publisher so it's gonna create something called - publisher reflex which i think is kind of nice so okay now let's go ahead and run our server again and let's get this going so what we can do now which is quite cool is in our a tags here we can add a couple of things so in my publish I can say data reflex equals let's see I want to put this on some different lines here can I get a little bit easier to read so data reflex equals and then on click I want to specify that I want the publisher reflex to call the publish action okay so basically the syntax here is we call data reflex so we tell it which event we want then we tell it which reflex we want to use and then we say which method to call on that reflex and then we can provide some extra data through data attributes so we can Datta host ID equals and then we can say post at post the ID right okay so let's do the same exact thing for unpublish let's fix this back to the secondary and then here I'm gonna call unpublish and then down here let's change this text to be unpublish okay so now let's have a look at that reflux class that was generated so we have this new folder here reflexes so let's look at the publisher reflex I'm gonna go ahead and just remove all this documentation and comments that are in here so I'm going to create two methods publish and unpublish so let's think about what we want to happen so first of all what we get is we get access to an element so whichever element and the sort of default setup you can do this on a little bit fancier ways which we may get to later but right here we have this data reflux defined on this element so this element carries along with it it's sort of HTML properties so we can call things on it which we'll see in a second like we can pull this post ID off so what we get what we're gonna do here is say post equals post fine I will say element data set and then what we want to do is say post ID like this so it kind of works like params in the controller so I want this on both of these reflex methods and then what we can do is a post update and then we'll say published true published at and then we'll say time dot now and then we'll do the opposite on unpublished so we'll come down here copy this so published is all published at is nil so is our server still running or no yeah I would just restarted it okay so we should be good to try this out so let me refresh and let's see what happens if I click publish once it finishes reloading so it's gonna make me log in again I think I have an issue with the office and this has something to do with action capable and authentication related to that I think it's a click publish you see straight away it becomes unpublish there's no page refresh there's no nothing it's just right here in place so let's add a couple of things that let us know that actually this is indeed published so in the top of our card over here above the forum so what we could do is let me see where this would be nice to put it probably be like right here we get to put so we could say if at post got published you'd say like let's say div float:right and then well no let's not do that let's just make it a div and then we'll say badge I think he's a thing and then badge say primary and I'll say published and then just outside of that let's call this a span instead of a div and then right here will say published and then maybe we could say something like time ago words and then at post published at and then maybe this needs to have a margin right sorry I'm just making all this up on this spot so I don't love the way that looks but that's okay well we'll change it up I just wanted you to see what happens if I click on publish now so you see that that ships immediately appearing and disappearing and so this is like really really reactive kind of style programming so it's quite cool I got to find a better place to put that but for now I think that's a really cool little feature actually you know I'm just seeing something here I think I'm gonna add a little header section on both of these and we'll see what it looks like so if we come into our card over here where we were editing this post and we do div card header and we bump this up into the header maybe we make this an h6 so that it's quite a bit smaller and see what that looks like so I need to give that card you know what's actually what does it look like if I don't have a card title of this maybe let's do card title mb0 okay that's looking better then what I would like to do is over here on the top of my card I want to have a card header as well and I think I can do like this text-align:right and then let's grab this and cut it now don't want the badge actually I think I just want to have I think I just want to have published time ago in words ago else and we'll say unpublished so let's see what this looks like now so that's not that's not right with the class but that looks okay so I'll say let's inspect this really quick I mean just do a quick check here I do text-align:right this that's what I wanted to look like so let me check the bootstrap class for that bootstrap class align text right maybe text text okay so it looks like we can just do text right okay so that's cool so we just need to say text right and I think what I want to do here is actually make this bold so let's check out what this looks like cool so now if i unpublish unpublished published so this looks really nice so the next thing i want to do and again like I'm kind of taking some time because I want to make this look really good it's part of this lesson /i episode for me is making this look good so what I want to do is actually set up font awesome so font awesome is really cool if you haven't used it before if you click start for free it'll take you through getting set up I'm gonna go ahead and just paste in my author's dot HTML that yarby you're gonna paste a script tag down here that's going to essentially load the awesome stuff for me so let's come over here to the icons and let's do a search for paragraph and see what suggestions it gives us okay so that's actually fine it's literally paragraphs we'll copy that and what I want to do is up here I think I think I actually have to do this in a strange way here so I think I have to do button type is submit class BTN BTN dark do doing this from memory so hopefully this works out okay so pasting our paragraph icon and I'm just gonna go ahead and cut my previous one and let's see what that looks like okay doesn't have somebody that should be forum button tag okay so let's see what happens if I click it so now I have a new tags down here okay cool so that's nice and then I want the same sort of deal for image now let's see what this prompts so I kind of like this one just image that makes sense so we'll do the same exact thing down here button tag type submit class BTN BTN dark I'm gonna change that in just a second because I don't really care for how this is looking and we'll paste that image icon in there so let's change this to be I guess we do we could do a few things here let's try it info if we had a lot of these this isn't gonna look right in an actual fact maybe what we need to do here is say secondary that's kind of a medium gray and then maybe up here we make the back button actually the dark since there's one of those let's see what this looks like I'm gonna have to button I forgot to take away my submit here so let's go see what that looks like not completely crazy about that to be honest with you but I don't know we'll think about it let's add a few things here so let's see how's this looking I think it's pretty ok except for these deletes so I want to fix the delete we're gonna build out some real content in just a minute so that this starts to look a little bit more put together because right now it's kind of it's weird with very empty content I guess so let's fix this the lead button here so how can we go about that so that's down here on our image I think one thing we might do is get rid of this div and let's move this up to the top let's make this an icon again actually and let's see what icon I think it's I think it's close we do this from memory let's see what this looks like okay so that's not it so let's do close window close times it's times I think is the one that I want so we'll say FA times and I actually want to bring this over on top of the image in the right so let's play around with this a little bit in terms of the positioning and see how we can do that so what's happening on that so is it floating I'm gonna take away the float right let's take this and let's just write a little custom CSS here so position:absolute right:0 so the the image is 80% wide so if I make this 10% should be sitting pretty good so let's make this 15% so that's not going to get us to be exact probably what happens if we slide this in so it's kind of weird I don't know if it'll make more sense to use that as like a background image and then place this in the side hopefully I don't know let's make it I say 14 15 is it 10 Sara way to get right on the edge of this thing I guess not right CSS is not my specialty to say the least maybe maybe if we do 10% plus there's a padding of some sort on this thing so what's that amount of padding that looks to be about like 15 pixels let's see if we can find that down here so that's 16 pixels I think so the calc 10% plus 16 pixels that should probably be just do like it's really ridiculous that's not gonna work as we go up we're probably even on other images so that's not gonna be perfect probably in most situations let's see yeah - so we move it in well seems to pop into place okay that's a really weird one so let's see if we can get that to do all you want so we're in the image we're gonna do let's see so that's the let's call this the delete BTN so okay image dot delete button paste those things in there so then I want to actually make this beat see in dark maybe see what that looks like I like that a little bit better it stands out a little bit less and I'm actually gonna make that let's see here opacity 0.7 or something like that let's see how that looks and then maybe on hover and hover opacity should be one so that looks a lot better cool so alright that's pretty nice on the design Friday I think so let's go ahead and try to build this out with some semi realistic looking content I'm just gonna go over and grab some lorem ipsum text sort of just for filler and I'm just gonna grab this and probably copy it a few times a few places so what we want to do let's make this a headline make it bold maybe let's split these kind of like we're writing an article okay so that looks pretty good let's generate another lorem ipsum let's just make another paragraph here so we'll type or click that paragraph there and then make this kind of split here maybe this is just bold and the wall kind of create a few little paragraphs there I don't want to delete save and I think that looks pretty nice so let's add in an image and so let's suppose that we actually let me go over and grab a new image tired of looking at some of these so if we go over to pixels and just search for like city let's let's search for Europe or something so they've been why not this one why not so just drag that over on to our desktop and then I'm gonna bring that in so we'll save that and now what I would like to do is what happens if I want to put that image I think it's gonna save that is a new one for me database is locked well refreshing the page seems to fix the problem so one thing that's bugging me is that the bottom of the page is up against the bottom of this card so I'm just fixing these little style things as I see them right here I'm gonna give this an MB 5 so that it should scroll further past so that that's not budding right up against the bottom of the screen but what I would like to do is actually be able to grab this and drag this up here and put it in between these two paragraphs to do that let's jump back to the terminal and stop this server and I'm going to add a new tool first of all it was anything running over here No okay so I'm gonna add a new tool to our JavaScript called sortable j/s I have a separate video on this if you want to watch this a little bit more in-depth we'll run that and then start our server back okay so then if we jump back to the code and we open up application jas I think we should be able to import sortable from sortable jas like this and let's see what I'm gonna be looking to do is essentially have something like this let element equal documents dye gets element by ID and then we want to have something like elements and then what we can do is say something along the lines of sortable dot create elements and then I'm gonna give it a option here for animation and save at 150 so this will make more sense in a second we don't actually have this elements thing yet so what I need to do is each one of these paragraph and down here image what I need to do is wrap all of this in an unordered list and so I need to start here oh boy that's going to be hard to see what's what [Music] let me see if I can come down here maybe I can cut it and then I'll see so let's just do a guess here and say it's that one so I missed one okay I need to probably move some of this stuff into partials so it's a little bit easier to see so then we'll just paste that in there and that looks like it lines up okay so fingers crossed then what we want to do is essentially write inside this if element is persisted you're gonna put an li tag and instead of going through all of that trying to figure out what's what I'm going to come all the way down here to the next to last in tag and then do Li like this so it's going to fire our servers writing it's refreshing we should see little dots on the left if this worked like it there are lists items now yeah so that's what I was anticipating so let's go over really quick well let's do this so we want to give this an ID of elements like that and then in our base CSS we can say authors and then we'll just say elements list-style:none and also I'm going to say padding left zero I think is the way we do this and now that should line back up okay so that's what I was expecting but since we added that sortable code I think see how we can drag and drop that now so that's pretty nice it doesn't save and that's important to point out but it does that it does let us move things around so that's pretty slick so we're only refresh this doesn't save though so now we need to hook that up I just noticed one little thing that's sort of aggravating if we click this cancel it actually refreshes because we're not preventing the default so what we want to do here say in this click so here we're matching on cancel and again there's a whole episode dedicated to this so I'm not going to rehash the whole thing right here but right here once we get past this if statement we're assuming that we're in the cancel so I'm going to say event dot prevent default and yeah I think that should do that so it's refreshed and let's see what happens now so if I drag this up to the middle and then I click on this and click cancel it doesn't actually go anywhere now so that's good okay cool so that's what I wanted to fix so to get going with actually saving this data we're gonna take a look at stimulus and j/s and we're gonna just take a quick look here it they have this set up with their quote unquote hello controller and their little example so I'm gonna copy this and just kind of show you how this works really really briefly so let's just stick this at the very top of our page and then they already have they have some hello code here and because we have stimulus reflex installed and it depends on stimulus if we go inside of JavaScript controllers we should already have a hello controller so I'm just gonna paste this in here and let's go refresh our page and let's see what this is looking like so I always do these little sanity checks just to make sure I'm not going crazy and that this works how we expect so so if I put my name and it prints out so we know this is working so what I want to do is create well let's create a controller called how do we want to do this I guess we could call it like sort let's call it elements controller to be sort of generic so we can create that here new file elements controller dot Jas and I'm gonna just copy this code and we're going to modify it and so we don't need to do anything to this we don't need to do anything to this we don't need any of these things what we want is a method called sort and I'm just going to for now console dot log and we're gonna say sorting elements something like that okay so far so good so let's close down some of the stuff that we don't need here now let's copy this or cut it rather and let's take it and let's put it closer to where we're actually working so just gonna stick it right here so you can look at this and see what we need so we need a data controller so we have this div card body that's wrapping around all of our elements so I'm gonna go ahead and just make that my data controller so I'm gonna say data controller equals what do we call that elements so the name here has to match the first part of the name before the underscore controller and so this is how you say hey everything in here is dealing with this elements controller okay the next thing we want to do is specify something to sort of listen to so this on on this to an action essentially so this in this case is a button sorry I'm stuttering we can say when a click happens on this button trigger the hello controller greet method and again these are these JavaScript controllers what I want to do and I'll copy this kind of being lazy say the data action here is drop a nun drop I want to trigger elements and sort and let's delete all of this and let's go back and let's refresh and see what's going on so now our little demo at the top should go away and let me open up the console down here and let me move it to the side so we can see what's going on so let me try to drop something and we got nothing so I did two things and there's a weird thing happening with stimulus and maybe I just don't know what's going on well enough frankly but I had on the only two things I've changed is I had on the mobile simulator so I turned that off and I also did a hard refresh with command shift are on Mac I assume there's a similar thing on Windows and now if we drag and drop you see here we get sorting Elements printing out so that's basically where we were trying to get to but yeah so that was a little annoying but now that's working so that's good so to sort all of this stuff we need to do a couple and sort it and save it on the database we're going to need to essentially pass some data along to the server and tell it to make an update and so we can do that well we're going to use stimulus reflex to do that actually but we need to provide it with some data and this is a little bit more of an involved setup than our previous one was so what I want to do is add for each element I'm gonna say data elements ID equals elements the ID and actually I think I'm just gonna say data ID I think that'll be fine I think that's about it actually so then over here in our stimulus controller I'll actually need this I was experimenting trying to fix my problem and ended up not using that at all so what we need to do is first of all let's let's see so the in any event so no matter what's happening we're gonna need to pull the let's see elements that's kind of funny elements elements let's let's just call it elements equals document dot get element by ID actually we could call this the elements element which is kind of strange now let's leave it I'm sorry I'm gonna quit bouncing around on that and then we'll just say elements and then we want to get the essentially what we want to do is get the we need to add a class over here something else regarding class equals element item like that and in actual fact I'm sorry I keep going around my semantics here but this is gonna be important so I'm gonna say let element equal that and then I'm gonna say let element items equal and I won't say document get elements by class name and I want to get the element item like that and in order for me to make this work I need to call array dot from on this and we cover this in a recent episode on drag and drop and so I'll let you take a look at it there and then what we want to do is say let well I guess I can just call this elements this is getting really tricky because the naming here is hard because I'm trying to use the naming to talk about HTML elements but now my database object is also called elements let me think about the naming in a second let's get the code working in at least so we're gonna say element items dot map and then that's going to take an element and it's also going to take an index and what I want to do is return an object which has an ID which is going to be the element data set I think I can call ID and then and so that's being pulled from if you're kind of new to that to the whole HTML saying that's coming from this data right here data - ID on the JavaScript side translates like this element data set I think I don't mess up some syntax somewhere and then I want to say the index actually what I want to do is say position this index plus one in an actual fact well I should be fine I should be fine so let's consult about log elements and get a look at what's going on whenever we drop something so let's refresh and I have a problem what did I do there's got to be an error in here somewhere unexpected token on line 54 9 8 maybe map element didn't like something oh I need an arrow whoops let's try that again okay so let's try to drag something and see what happens so we get three objects we get the ID four six five and now the position is one two three and so what we're gonna do is basically save the position on the database now and that's essentially going to keep us then we're going to order what's listed on the page by position ascending so I assume that this this element has a 90 of for this one has an ID of six and this one has an idea 5 and now because of how they're displayed on the page they have the relevant positions so how do we go about doing that so what we can do and we're going to pass this element to stimulus reflex here in a minute and when we do if you will recall over here in our publisher reflex we're dealing with this element data set so that element is essentially going to be sent by us here and so the way that we use this before was sort of the default implementation of stimulus reflex right now we're going to be using a little bit more manually built out kind of way of doing it and so you have to actually tell it what the element is going to be and we're going to actually send along some data in this element so we're gonna say element dot data said that elements equals and then I'm gonna do JSON dot stringify elements here like that and I don't need to console about log that now and so that's gonna get our elements ready to be sent now what I also need to do is instead of using this controller here let's take a look at this publisher controller so what we need to actually do is use all of this stuff so this is gonna make this a stimulus reflex controller or not just a stimulus controller and again I have some other episodes on stimulus reflex if you want to check that out a little bit more in depth but let's go ahead and update that and then I'm going to get rid of that comment there so since this is a stimulus reflex controller we have this method that's been added called dis stimulate and what we're gonna do here is pass in essentially a stimulus reflex with a method that we want to trigger so what we can do is say something like elements reflex and then the method we want is probably sort and then we can give it the element that we've been working with here so what we need to do is come over here to the reflexes create a new file and I did this automatically last time with that command but I'm doing it manually this time so we'll say elements reflex ty RB and essentially what we want to do is say the same thing we did over there so we'll say class elements reflex inherits from application reflex and then in here we're gonna have a deaf sort and all we're gonna have to do in this sort method is essentially this will say elements equals element dot data set elements and remember we made those into JSON string in order to pass it over here so we'll say json dot parse this and then we will say elements that each do elements and again i think this is not the most efficient way to do this at all let me know it's not but i'm not gonna worry about it in this simple tutorial so maybe we'll come back and kind of refactor this later i'm trying to use my time running out of lay the foundation for some interesting stuff now but we can come back and add more advanced stuff on top of it later so i'm gonna say elements record equals element dot find element dot what would be ideal ike this and this data set actually is i dot it's a it should be like this probably and then in actual fact that's gonna be a string most likely once it's the parts from json so we'll get the element record and then we'll say element record dot update position element position and as far as I can tell that's probably it so let's refresh should take a second probably and let's try to drag and drop our image up here a lot of second apparently I broke something I got a javascript error screaming at me unexpected token elements controller what line that's a line five wasn't this just working oh I know what it is I think I'm missing that that's what it was probably so let's go ahead and try that again let's keep an eye on the console over here and see if it freaks out on me this time nope okay so now we're dragging and dropping and let's refresh and it did not work so let's check our terminal over here one thing I'm gonna do and I'm gonna open up my gem file and in development I'm gonna add Jim pry pills and you know I've been using Prai for so long and it says I can use console so I need to learn that I guess since that's probably the officially good way to do that now but for now I'm gonna stick with what I know since I'm in the middle of making a video so what I want to do is over in [Music] over in my element reflex let's put a binding doc try right here and see if we're even hitting this okay so I don't need that open that's good to get out a little it's gonna force me to log in again probably even a tech maker TV okay so let's drag something and drop it and let's see what happens here so nothing happened there see if I got any errors over here error invoking this that stimulate is not a function you know what that's kind of weird hold on a second oh my god I think I've just been staring at this too long skinny aleut is not a function okay so false alarm I'm gonna go ahead and comment out this pry we may need it we may not so this should be stimulated in the Aleut if that's a word it sounds like something you do in organic inorganic chemistry class or something which shows you how much I paid attention in organic chemistry so let's try to drop something again so let's do one thing really quick it's dropping and you can see all this stuff being printed out here by stimulus reflex one thing we haven't done is actually in our edit what we want to do is say elements dot order position ascending and let's go check what that looks like so now have a look at that so we've got our stuff drag and drop sorting now so if i refresh the page you can see that that's saving there so how cool is that so the last thing that I want to do in this episode because this is getting really really long I want to actually try to build this index page out just a little bit more and I want to go ahead and actually add a little more content so that we get more kind of realistic looking descriptions on the front page this might actually be a little bit long let me just trim that a little bit there and let's give this a really good title so let's just go to like mashable.com somewhere and grab a headline maybe not about kovat 19 because that's a little depressing let's do SpaceX sounds cool right so that's a headline and then I'm actually gonna choose a different header I'm in here not at all related to rockets and so we'll go ahead and update this and let's go back and check out our homepage so that looks pretty good then let's do the same thing for this test number two let's just grab some other headline goodness gracious that's an aggressive website okay so my computer is actually heating up right now as I'm on Mashable so I haven't been on there in ages it's just the first random thing that popped in my head so that's kind of crazy so let's grab one more paragraph here and choose us a file for the header and let's go with that one and okay so now that looks a little bit better what I want to do on this page is essentially so this is my index here where are we inside of this what I want to do is add a span with a class badge and essentially what I want to do say if Post published that is crazy my computer is cooling back down that website was literally overheating my computer probably because I have other stuff trying like the recording software or whatever but that's still that's crazy so if the if it's published I want to give this a badge primary and say published something like that else I want to give it a badge of secondary say unpublished I think unpublished see what that looks like and I'm gonna on both cases I'm gonna give that an MB - all right that looks pretty good I sink on the header I'm gonna give that a and B - also so that gets bumped down maybe actually I'm gonna want that to be three just gonna tweak this a little bit here yeah I think that looks pretty good so that is the foundation for a pretty cool admin area for building up some blog posts so in the next episode what we're gonna do is actually build the public front-end because remember this is only the backend for admin or authors rather so got a handful of other things I want to add here I want to add some filtering so that you can filter about publish or unpublish or maybe eat something else I want to give you the ability to add tags so we'll probably get to that at some point I don't know how many episodes I'm gonna do on this I really find this to be kind of a basic topic that's kind of people will think it's simple but like there's actually a lot of cool stuff you can do in here so we'll see what happens but yeah so the next episode we're gonna focus on building out the public front-end so if you enjoyed this very long episode be sure to subscribe to the channel give the video a thumbs up and leave a comment but I will talk to you in the next episode
Info
Channel: Techmaker Studio
Views: 17,200
Rating: 4.955801 out of 5
Keywords: rails tutorial, rails 6, building a blog with rails, rails course, ruby on rails 6, beginner blog rails, rails 6 tutorials, new rails 6 tutorials, learn ruby on rails, ruby on rails for beginners
Id: MCEzxY9BbiU
Channel Id: undefined
Length: 138min 38sec (8318 seconds)
Published: Tue Jun 16 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.