- Read Tutorial
- Watch Guide Video
I'm going to go ahead and start up a new app. We're going to go ahead and use PostgreSQL that's what you will be familiar with. We will start with rails new, and we'll just call this class curd app. I don't want I don't want Tests because we're not going to be working with the test environment and I do want a PostgreSQL database. rails new class_crud_app -T --database=postgresql
Create a new app.
I need to make sure my PostgreSQL is running, and that's needed that if I'm going to use PostgreSQL.
All right so I'm going to CD into my project
Then use the open .
I'm going to drag that into my sublime left-hand window.
Now we have an app, So I'm going to go ahead and run the rails db:create
to create our database.
I'm going to run a rails db:migrate to give us our schema.
This is your database file you'll see the only file you start with is the seeds file.
If you do not run your migration it will not give you your schema.
So it's until you run a rails db:migrate your schema will actually not be populated.
The idea behind today is building out crud function for blogs by hand. So we're going to walk through this rails g resource and we're going to call this blogs! We're going to pass and data types and of title:string body:string and for the heck of it I'm going to date:date and ranking:integer. I'm going to create the rails resource generator.
This is going to give me a migration's file
You do not have a schema until you db:migrate and your schema will not update until you do migrate. This migration file was not here before we ran this resource generator because the resource generator provides us a migration's file. It also provides us a model to talk to our database for the blogs table, a controller and then it provides us with an empty view file.
There is there are no files in here. It does not give us all of the code like scaffold does. The resource gives us that empty view file and it gives us an empty controller. It's giving us the outline that we need to create crud but it doesn't actually do any of the code writing for us. The resource generator is a lot skinnier than the scaffolds. Here's my migration's table this is where I'm going to verify that this is how I want it spelled.
These are the data types if I want I can change this in here before I run the migration. So if I had misspelled anything in here that I want to
change, I could make changes these changes before I migrate nad save the file.
(Make sure
it's title
and not tittle
.) When I run the rails db: migrate, and the changes I make in the file are what would create the table.
Question: Before you do that Andrew. Today day I was working with Aya actually, and she ran a scaffold that she shouldn't have by accident. She migrated her database to then it changed everything. We would have to destroy the scaffolded which rails has a built-in command to do that. And then you. There is no need to migrate the database because there is nothing changing. In her schema file, it still showed the table of the deleted scaffold.
Answer: Correct.
Question: Does that update over time or is there already a command that you have to do afterward. What is protocol?
Answer: What's going to go on there is you have to go in and tell the database to drop the table if you want it gone. It's not going to take effect on it because you deleted any code this can be access to the table right. If she was to push that up to say Heroku, it's going to set up that schema and that database based on the migrations in the migrations file. So by deleting the scaffold, she would actually have the correct tables in the schema on a remote server. She would not have them on her test/development server. What matters is that these migration files need to be correct before you push live.
Now you can clean up the schema in multiple amounts of ways. You can drop tables or reset the database. The way I do it in class because we're in a test environment is I delete the entire migration file, reset it, and drop it. There's a lot of different ways to do that in the test development environment. What matters more is once your product has gone into a production server you are not deleting or changing databases except through migrations. You could mess up any data you have in the database at that time. So we are going to do the rails db:migrate
. Now my schema has been updated.
So I now have the crud functionality in here and to verify that we have the connection to the database. I'm going to go to the terminal and run rails c
. The first thing I'm going to do Blog.create!(title:"text", body:"Test", ranking: 1)
I'm going to pass the title a data of "test", and then I'm going to pass body the same string "test". I'm also going to call it a test just because that's all I'm doing right now. I'm keeping it simple as simple as possible. I'm not going to pass in a date, because I don't want to type that out. I don't have any validations right now, so that doesn't matter. I will pass in ranking as an integer of 1.
You notice it is not in a string like the other two it's an integer, so it's not in quotes. I'm going to make sure that my database is accepting data.
See here we begin a database transfer, and here we commit the database transfer so that both take face and to verify that I'm going to call blog because that is our model. Blog.all
and see that we have one blog that has been created.
Question: "What does the bang do again?"
Answer: "The bang will return an error if this runs incorrectly." Here is an example, if I come in here and I call this "tittle" and try and run it.
The bang is what's allowing me to get this error saying this is an unknown attribute. We do not have this attribute in the blog model for "tittle" so it is saying this doesn't exist in the database. That helps us verify if we just mistyped anything. If you use control D in the terminal, it will cancel the rails console.
We're out but if we go to our terminal and type in rails s.
I'm going to open a web browser and type in localhost:3000. The web page says "Yay we're on rails."
But if we try and go to localhost:3000/blogs. You remember if we ran scaffold this would be our address to go see all our blogs.
We're going to get an error saying the action index could not be found for the blogs controller. So the first thing we're in a remedy is I like to follow a process known as red, green, red programming where I intentionally cause an error. I then fix the error and then I check for the next error. Our first error is we do not have an action index. That tells me as I am missing a method for index inside of our blogs controller.
This is also known as an action when it's inside of the controller. So that's how you can read this error report. Now if I go refresh this again, we now have a action but saying we're missing a template.
So to provide that template we need to go to the blogs folder which we know is empty and we know we have the method now for the view. So we're going to right-click "new file".
We're in a save, and we're going to call this index because we have to match the method name index.html.erb
.
I'm just going to pull in H1 tagging here, for now, I'm saying Hi there.
Just to verify that we are now reaching that page. So now I'm going to refresh and as you see we now have an active page.
Now our page is not showing anything so just to verify again that our data is correct. What we're going to do is we're going to make sure that we can pass our data through so we're going the call this @blog = blog.all
We're calling our database restoring the instance variable.
Now we have that information; I can go back to the view because we have to make this database connection by doing this blog.all
. We're saying go to the model hit the application record and pull from the database, whatever we have requested here.
which in this case is all the records which are exactly what I called down here in the terminal. When we were testing if I created a record I call Blog.all
to test for our record attribute right here.
That's the same command I'm running here to get that information. So we're ending the index page, and now I can do the embed Ruby tag.
I'm just going to say <%= @blog.inspect %>
. When we refresh the page, we now have our database record here with our one blog.
All right so we know our is working, and our data is flowing to our index, but this is not exactly what we want. So at this point is where a lot of people tell me as a well I don't know where to go past this point. If you don't know where to go past this, what I suggest doing is opening up a second project. I'm just going to go back to any one of my projects that has crud functionality.
I'm going to open up the blogs controller. I'm also going to open up the different views that are available for the crud functionality for blogs. For this at I want to bring in the index and now when I'm calling out for functionality, I try and read the pieces that I want. So in this case I know I want this because I want to iterate over each blog.
I'm going to bring in the pieces that I want here which is the blog title which I know we have for in our database.
We also have the body, and we have a date even though we're not showing it.
This one doesn't have a ranking yet, so we need the <%= body.ranking %>
.
I'm going to bring these in here even though they don't currently have a point because we do want a link to our edit and our show.
I'm going to our link to destroy action which we don't have yet.
But I'm going to comment all of these out because I am not going to be working with them just yet. So I don't want them to be in the way.
I know we're going to need them later, so I'm just going to save myself a trip. I am also going to end the loop.
Now if I go back to our view and I refresh, I'll get an error.
It's because I called it blogs on the view page and it should be blogs in my controllers it's blog. I'm going to change it to blogs because when I'm working with all of the blogs. I like to leave it plural if I'm working with multiples of data I like to call it a pluralized variable.
I'm going to refresh, and you see we have test test 1.
What we need is the restfully crud functionality. We have our ability to read, but we don't have our ability to create a new blog. If I go back to my red-green programming than I try and go to http://localhost:3000/blogs/new
what do we get?
We have an error that says "the new action new could not be found."
So I'm going to create a method new, and this will give us a missing template error.
Are you starting to see a pattern here? You can use these error reports to build out your apps. That can be a great tool if you've forgotten where to go and say hey I don't remember the next step you can go to the error report and you can read where to go next.
We will make a file called new.html.erb
. Now if I refresh this, we now have a blank page.
That is not doing any good here. Currently, we are still not creating anything new. So really go back there control controller when to check out our new action.
I'm going to open up our new file, and it's saying "render form".
Now, this is where some people get really can get lost because of this form. This form is this partial right here.
So for the sake of this one, I'm going to follow the exact conventions that they're doing here, and I'm going to create a new file on them the same, and I'm going to call it _form.html.erb
.
The underscore which declares it a partial and then we call it _form.html.erb
. What we do here is I'm going to go ahead and copy over the form because we are going to need it.
We're going to have to change some of the file to what we need. So we're doing a forum for blog. That's OK. We can work around that.
Blogs.errors.any is all fine because we're using the data type blog. If I'd call our resource generator posts, data collections, or anything else than blogs. We would need to change or naming convention because it wouldn't make sense with blog. This has a form for the title, body, and data.
We're still missing our rankings. We're going to go ahead and put that in here.
To verify this ranking here. If I in case I got it wrong I would double checking my schema to make sure I spell it right. But in this case and happening is correct. We just did it.
All right so now I have this form, and now I'm going to compare new pages again and so I'm going to bring in this render form. I'll bring in this H1. And I'll bring him this back button.
Now if we go back to our view and we refresh that page, we now have our blogs.
Now, unfortunately. What did I do wrong here what is this ranking doing?
Student: "It's giving you a date."
It's giving me the date, so this is where a copy-pasting trip a lot of people.
I went ahead and did that here so you guys can see it. I want you to realize why you can't just copy paste. If I remember correctly, I think number field. There's a number field.
You're not going to remember it. I remembered that from just having done it before. If I didn't get that right on the second time, I would have just gone and google it for time's sake. Now we're going to create a new title and a new body. Select the date and ranking of five; I'm ready to create a blog.
We get the action create cannot be found.
These errors will walk you through every step of the way. It's sometimes something you just have to remember you get used to. So now I need to go back to my blogs controller on both pages. I see right now I haven't written hardly any code from memory I'm just using this as a reference. So I need this action.
I don't need json because I'm not working with json so I would clean that up and I don't need this Json.
Because again I'm not working with Json, so I only need these redirects and let's see if that fixed our create actions. So we're going to go back to our view. I'm going to refresh our form here and create that we get unexpected end of input expecting keywords and in our blogs controller for saying line 22 we expected that end, and we didn't get it.
I did miss an end with my copy.
So back to our view and I don't want to refresh that I want to submit this again.
All right undefined method local variable or method blog programs for the blogs. Now I'm calling the method blogs_params
here that I copied over I don't have access to that currently. The error is walking me through the next piece, and this is the blog param which is down here.
The blogs param is inside of a private method, so I'm going to call this private. You can see I'm doing a lot of time deconstructing and reconstructing what I need from an app that I've already built.
I'm doing this partly for time's sake, and partly so you guys can see what I'm doing. All right. I'm going to bring in this Params. Now we have access to this blog Params. Now the Important thing to note here this param requires a blog. It permits title, body, and date. It is not currently permitting our ranking. We need to add our ranking.
let me go back and resubmit our form. Now the action show could not be found for the blog controller.
Alright, it's saying we're now missing the show method, so we create a new method called show.
Now we're missing a view template. We're using file and saving it as show.html.erb.
Q: "You don't need a new template for every method in the blog controller?"
Answer: Correct, I don't have a template for the create action and the create action is being redirected to a view. So we're saying we don't want a view for this we're going to redirect once it's been saved to the desired view which in this case is our show. You need a method and a view file for every page you intend to show the user. If a method is not going to display anything to the user such as create you usually want to redirect them to a page that the user can see. This allows them to continue to work around on your site.
Question: How do you know that that goes to show again? What does it show?
This is going to show page because we're identifying the blog by the ID. When I get to that here in a minute, we're doing about the ID of the blog, but the other way we could do this and that's a good point. This is a bit of rails syntactical sugar, and it knows that this @blog is trying to go back to our show page.
If we wanted to make 100 percent sure that that's where this was going we could do rake routes, we could find our show page, and we can do blog_path.
This will perform the same action that we have our show here. We'll verify that we'll be able to verify that, but this will do the same action just the @blog is a bit of a rails magic in the back end. If you get rid of the rails magic, this is the route that we're taking.
All right so let's put an on our show to make sure that we're doing this is our show page.
We're going to refresh this. I need to restart my server. I see this is our show page. Obviously we're not displaying this blog yet correct. We're going to that blog, but I could change this to one which would be the first blog we created, and it was not refreshed just hit enter. You see we still have the same message because we're not showing that blog information now we're just redirecting to a page. Now we need to work on our show that we can display the data. Let's compare methods. All right our show method is empty. Their show method is empty.
This controller has a before an action that is up here that we do not have.
This before action is calling this a method called set blog. Remember if a colon is in front of a word that turns this into a symbol and that symbol can be used as a method call. We set that method up down here. So that we're storing the blog parameters ID inside an instance variable called @blog.
What set_blog
is doing is it's making this @blog
method available to all of these other methods or show or edit or update and destroy.
So that we don't have to put in this line of code in all of those methods. Is that kind of what Jordan's been talking about what we're gonna do to replace the line of code that we keep entering in the same time. Exactly it's exactly what he's talking about. I'm just going to jump you guys straight ahead because you're never going to do that again once you realize it is this is so much easier later. He's walking you through how to do it because it's important to realize what's going on and it and that sort of why I'm talking about it but I'm not going to do it here because that would be a waste of your time and my time because we want to make this available everywhere.
We don't want to put this code in four places when we can just set it in one. So we're going to set bring over the set blog a and bring over the before action. Now if we go back to our show page we're still not going to have anything. Because we have nothing rendering yet on our show. So. Next step we're going to go back to our show page here. And you'll notice that. All right. Our show Page has this I.D. notice and we're bringing in this information and we're displaying these pieces so we're going to go ahead and pull all of this code and we're going to jump right in here. So now if I go back to our view and what this is doing here is this is literally calling this instance variable which is being set right here through the set blog. You can see that that is that set blog is making it available to our show action by highlighting it any you can see that they're actually the same method. Here on my syntax here.
So is making the app blog available which we are then calling the title display the body displays the date display and we need our Ranking display. Now I got lucky on this one because you saw I chose a blog out from random from all my previous projects that happen to have crud. It just happened to have three of the four that I chose today. So I got lucky. You're not always going to get that lucky you're your crud that you could be trying to copy may not be identical at all. I'm really sort of glad it is identical today because I think it will help focus on how much code you can copy over and all you have to do is change it since variables. Some database calls things like that. So you're not always going to get that lucky if you're trying to bring your crud over from another app. So we're going to go back to our view and now we refresh this.
Now we're successfully displaying and you can see this is the first blog we created through the terminal. If I change this to two you can now see this is the blog we created on our Web site. And our back button is actually working because it we're using the same naming convention to go to our blog path. Me Our edit path not the end of our edit. It's still not functional. So if I went back to our show and I tried to edit we'd get an unknown action for editing. Which brings us to our next piece as you go to you find an error.
All right So now we need our edit functionality workflows of the show reclose of the new we're going to close out the index OK. Now we need our edit so we're going to go back to our when we close out Blog controller and we have index show new and we need EDIT Okay. Now one thing I do for code organization and this is bugging me because I do this every time because they are related. I keep the new and the create next to each other because you. The new is the page where you get your brand new form and the create action is what happens when you save it. And I put my edit next to my update. Because they are also related. Now the fact that I know that they're related and that gives me the ability to come in here and sort of skip a step because you can't have an edit function without an update and you can't have a create without a new. So they're they're very interlocked. So I usually leave them right next to each other because if I'm going to work with one odds are I'm going to be working with both.
Does that make sense. OK. So I'm going to bring in both and I'm going to get rid of the json because I don't need that code for this app. I do want the rest of this and I don't need to do anything else there because our set blog is also making that into this variable available to our edit. OK so now we have the method.
Anybody have an idea with this next area is going to be it's going to be a template. Well done I think we're getting into a pattern here.
OK so we're going to say this and we're going to call it at it. edit.html.erb . Now refresh us again. We are now successfully going to our edit page but again we do not have any of code. We need to display it so we're going to open up the edit here and as you can see it's rendering that exact same form that we created earlier that so we don't have to have this code in three or four files.
We can have it in one file And we can use this render call to populate this code at this point of our page. That's what rendering is doing is it's literally saying I'm going to go through this form I'm going to find this code and I'm going to bring it in. At this point. So because we followed standard rails convention.
Now being able to copy over more and more code just directly and have it run properly. So our edit is now fully functional if I update the blog you see. UPDATE If we go back to edit and we changed this to two are awesome and edit and we update the blog. You see our edit and our update functionality is now complete. So now that we have all those I'm going to go back to our index where I had these buttons commented out. You remember these. I'm going to now uncomment these so they'll show up on this page.
OK Now this is obviously very very ugly but I'm not worried about design right now I'm more worried about the functionality. So now we have are we now we know we can create a new app. We can show an app. We still have a link here for the new. So I'm going to go. I'm going to borrow this one. And when we go underneath this loop here and I want to just call this new and wherever I find the route to our new page. Routes rake routes.
So I'm going to go find our new blog here and I'm going to put in a new blog underscore underscore path perfect where you say that and once I refreshed this after I restart the server we now have a new here and I'm going to put this in a paragraph tag because I just want it to show up on a different line. I don't want it to be hanging on the end of this destroy because that just doesn't make any logical sense. And now if I click new we go to our new form create a blog. Oh. Oh OK so we found a bug actions show controller blogs missing required key ID. This is actually very good. So this is saying hey we don't know which blog to take you to. Remember how we talked about how this blog was being our shortcut for our show. And then we built in the show path. What we didn't do is pass in the actual programs ID.
So where would you pass that in? So we would need to go to the blogs path. And we will go. We would go to @blog. Id i that might not be exactly right but I'm going to try and do this here manually so you can see the difference. There we go. Let's go back to our webpage and create a new one to make sure that it works by the way I'm very surprised I got that right off the first go. You have to pass the params I.D. and so it has to know that the blog you're currently working with and the idea that blog. Does that make sense. We're not passing on the params because we want to go this specific blog that is being saved right here. So we're saying this is our test. Anything we want and a ranking of four and there we go. So this at blog that we had originally is performing the exact same functionality of this manual path. rails magic all it's saying is hey instead of having to manually call your path we know you want to go to the show page for the blog you just created. So just call at blog and rails. We'll do the rest for you. And just to verify that that will work as we've just done this let's do at blog we're going to go back here and we'll do new again. Another great title. Anything in the body and we have a ranking of two and we create the blog and you see it the exact same result.
So if Andrew what was that. So that at blog method that you were calling that you had highlighted right there if you are into your private methods you also have a method called out blog that basically just finds that the the params ID. Right. Correct. That specific section is referring to that private method.No not that time. This at blog private method is only being made available to the show. EDIT Update and destroy not create or are new.
Interesting so that at blog that's been referencing the create method is right up here. [00:45:07][8.0]
[00:45:08] This I see is this at blog. So don't don't get confused with all the different blogs. It's just part of the naming convention. I could call this at dog. Now that's going to mess up some other things. But I could do this at dog and then this at dog and then this at dog end it would still take me to all of the same places so long as I went through and change the rest of the files. But this is the one that matters. Well and this one does make sense. These are tied together. These are not being set up here unlike the edit in the update. The reason the edit is being set. And I'm going to undo those before I comes back and bites me like the dog named that here. The reason I comes back are the reason they blocked the edit and the update one is because we need to be able to return the field in fields. When we go to the edit it's going to go make a database call and return all the information that was actually stored there and repopulate the fields for your editing. That's where it's going to go find in the database. The ID of the blog you were trying to edit cool for params is a built-in Rails function right. Or method. Yes. Which is why we if we're in a specified specify we call it blog Brams or something different to differentiate from the built-in Rails params. [00:46:57][108.7]
[00:47:01] All right so now we have our read our update our edit and what are we still have to do is strong. So if we try and go to destroy we get our message and it says the action destroy could not be found in our blogs. Controllers so means we need to come back in here and we need to compare our different pieces. And we're going to go back to our blogs controller and find our destroy action. And again I don't need json and I don't like extra code lying around. OK. So I'm going to bring that in I'm going to save and now if we go back to our view and we go back one more page and I try and destroy again you can see now we can successfully destroy blogs that is made available through this method. Now I brought in in the beginning and we're passing in the individual blog calling method delete and then we sent a confirmation method to them saying hey are you sure you want to delete this blog? Now. One of the reasons this is so much more popular than a scaffold is we now have full crud functionality correct? We're. This is what you guys spent the last two three days building out. We just built it out in 45 minutes. So it's not terribly long to build out except for your first timer too. But if we look at our folders here this was our scaffold folder. This is our manually created crud. You see how many extra files this gives us. We have all this extra files all these extra code. If we go up into our assets this gave us a blogs.scss. [00:49:17][136.3]
[00:49:20] But this one also gave us a scaffold.scss which has 89 lines of code that we don't want just in one file. So there is a ton of code that between the scaffold and a resource generator that generally you don't want from the scaffold so you'll end up creating it out by hand even if you end up using another scaffold or a previous project where you've done crud functionality to help you build it out especially the first few times. Now I've built this out enough that I could probably go through and build 90 percent of this doing the red green red that we started out and let it direct me to the next pieces and eventually you'll get to that point. But you don't need to do that because you have all these resources. Does that make sense. [00:50:21][60.6]
[00:50:26] All right it's fun fact Andrew makes you build the sound probably like another two weeks or maybe even a week or just the heck. [00:50:33][7.3]
[00:50:34] We have some extra time build up create functionality by hand. [00:50:37][3.6]
[00:50:39] It's the weekend homework. So now they have a video to walk through it. It's all nice. So they get they get a little bit of a cheap Headstart. [00:50:47][8.6]
[00:50:51] So any questions about that arose in general if they don't have any questions I remember one thing that tripped up a lot that some people were getting tripped up on. Now is the befor action within the controller or how. So I think a general recap would be good for people. [00:51:10][19.8]
[00:51:12] OK. So the before action this is saying before we run any of these methods. So before anything is run perform this action that's literally what it means. So before the file was run were to run were in a pass set blog which is our method down inside of our private section here. [00:51:34][22.5]
[00:51:35] See where we're calling it and we are going to pass this information to only these methods. So we're going to put we're going to put this information. [00:51:50][15.3]
[00:51:54] Inside of our show. And it updates and the last one is destroy yes and destroy. So we would have that code in all four locations. Without this before action and it would all run just fine. But with the before action we can remove the code from all four locations and just call this one before action so the read if we break this down even farther. Remember I said a symbol is a method. Most of the time not always in rail but most of the time. And then this when your column is after. One thing it's excepting information. So we want to pass it only. So it's bringing information and then we're bringing in an array of methods. So we're calling it we're saying make all of that available to this array of methods. [00:53:06][72.4]
[00:53:12] So only as a reserve time or is not just what you name the array that is a reserved turn for the before action because we only want it to affect these methods. [00:53:24][11.5]
[00:53:26] You can also do accept so provided to everything except these methods. And there's a few other terms you can put in there as well. So this is specific to the before action. What you are still loading the array into this data. So this is essentially a key-value pair. That we are then using to pass in the information that we have down here. [00:53:53][26.2][00:54:01][1.5]
[00:54:03] Does that make sense. I before action can be a little a little tricky. The first three times you see it but you'll get the hang of it. You only use it in a handful of places. [00:54:13][10.2]
[00:54:14] Where do we get that. [00:54:15][1.0]
[00:54:17] The set blogging method we declared down here inside of our private methods Yeah. [00:54:22][5.0]
[00:54:25] So this is set. blogs method OK that direct link redirects to here. [00:54:33][8.3]
[00:54:36] Right yes and whatever the id of that specific blog you were looking for. It's always the show. So this is pretty standard with a crud functionality you'll put this in your show edit update and destroy all of those need to know the data that's in the database just for the show we want to see the data for the edit. We want to change the data but we need to know what was already there. Update is directly linked with edits so they're essentially the same action and the destroy is where we want to go in and clean out that database entry so all of them need to have access to that specific unique blog to perform that functionality. Will. Any of the courses. [00:55:51][74.9]
[00:55:57] You think are being in enough I'm not sure yet. Everybody still sick but I'm hoping but worst case scenario I'll be out one more day. No problem. I'm hoping not. [00:56:10][12.3]
[00:56:12] If I am out again I'll try and do another one of these on another subject was of the students choosing so you guys can get more information and dive deeper in and get that instructor touch you. So hopefully this was useful to you guys hopefully it will be useful to those who aren't able to attend. Yeah. If there's no more questions I'll go ahead and stop the recording and then I'll post it into the channel. [00:56:39][26.7]
[3092.1]