Webinar: Tips and Tricks in Ruby on Rails
And welcome everybody. Here were the suggestions that came up. I was explaining before we're going to go through each one of these and we'll start up an app from scratch, like pure scratch, and only thing I'm going to run as a model generator and everything else I'm going to start out by hand which should I think get each one of these topics that you guys suggested.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So I went to the rails new. And we'll call this Class_practice_app, we're going to set the database to postgresql.

large

cd class_practice_app. So we have our app and we're going to do open .and drag file into your text editor. We currently have nothing in here so the only generator I'm going to run this time but first it's going to be a model generator. But first I'm going to do is rails db:create for our database and rails db:migrate for our schema file.

large

K look in our database we now have our schema but we have nothing else so I am going to run a rails g model and I'm going to call it post because we've been using blogs so much they don't want you guys to get confused with the fact you can't run other ones. And I'll say title as a string. And we'll just say body as a string because I hope to open up more of these later so we can keep this simple actually do this is a text.

large

All right. So a model post body text. This will give us our migration's file here. I'm going run another rails db:migrate so that we populate it into our schema. At this point we now have a database. We're going to go test our database in the rails console and I'm going to call post.create with a bang. And then I'm going to pass and title and the title is going to be my great title. And then the body is going to be body. And we will call this awesome body of work. As you can tell I do have a sarcastic sense of humor so I roll with that answer on that. And this shows we successfully created our database entry.

large

Now I'm going to call post.all to verify that we indeed have a database record. So we have a database record but now we need to get this to display to the user so if I set up the rail terminal that's I start my server you'll see that currently we have. "Yay! you're on rails!" If we go to our route's file which is in config /routes.rb. We have no routes currently so if we try to go to forward slash posts which is the naming convention we'd use for an index page.

We currently have nothing. K We have a model. Which is our post model that record. But now we need everything else that comes with it so we're going to go to our Controller and we're going to create a new file. And I said we're going to create everything by hand and we're going to call this posts_ controller.rb we're going to steal this from here because I just want to use this convention here and we need an end. But obviously we don't want this to be application control or what would this be... Yep it's post controller. And we're going to inherit the application controller. . Inherit from application controller.

Now to go with this. We need a views folder so create a new folder. We'll call this posts and we need to do our routes so we're going to open up our routes and we're going to do a we want crud functionality. So we're going to do a resources :posts. I think it's just that I might be off on my syntax there so whenever I'm not 100 percent sure I just open up a second app and verify because that's perfectly fine. All right now. So we have our route now which connects our controller to our pages and our model. We have our Controller. We're going to create an index page.

Now the naming convention because that was one of the questions because we're using a resources call in our routes. It is requesting that we use the standard crud functionality naming conventions which is new, update, edit, create, index, and show. All those standard pages so we're going to follow that convention here by calling our index. We're going to go to our post which we have nothing in and we're going to create a new file and we're going to call this index.html.erb . And then we'll make sure we have some text here. We just call this an H1 and this is our index. And let's see if we now have our index, in other words we'll see if I did this right.

large

So I did something wrong. Check our other app here. I want to verify our controllers and see if I got the controlling name wrong. But you need to make it plural posts. Controller it is plural. I mean in the class name. Oh yes I do need it plural. Good catch because that was the only difference. So let's go back and we'll check again. Now we have our index k so did you see did you guys see what the other generators are giving us for the control generator what the resource generator they're just giving us a file structure. You can go create all of that behind by hand.

We started out with just a model we manually created a post controller. I did mess up the naming convention but you caught the the air that I had there. So thank you. And then we need a host folder inside of views to connect that to and then a page and with our routes and our functionality works just fine. Any questions on that. So far okay. There are no questions on that. Now we need to talk about data flow. The one of the other things was data flow. So let's talk about how we exactly how this works getting our data from our model to our view and then to a separate view inside of another controller.

Okay. So I wanted to create all of that out so you could just see exactly how that works and what those generators are giving us. But now we know we have data information. So our model talks directly to our database and inside of here we could do anything that's going to do work with our model data. We're not going to get into that right now we're going to talk about how we can call that model and pass information to our index. Now you've done this a dozen times at this point. So I think you understand what I'm doing here. Everybody familiar with this so far right.

Okay so here is our data that we're passing to our index. @posts = Post.all And I'm just going to keep this very simple because I want to do a lot more than just the stuff you've seen all seen over and over again. So I'm just going to quickly just call at posts inspect dot inspect. <%= @posts.inspect %> I'm going to close out my ruby tags and this shows we have a database record here. OK so we now have that information. But I'm going to start a generator now because now that we walk through by hand let's just do a rails new or not new... generate controller. And lets call this call this pages because I love using pages and I'm going to call this a I'm going to have a title page and body page.

large

And that's going to be it for now. So title and body OK. So I'm going to go into my routes.rb. This gave us a whole bunch of thing but it included some new routes and I'm going to set our title page to our new home page So Im going to say route change the forward slash to pound sign. root 'pages#title'And now if we go back to our local host we now have our title. Now we haven't gone over creating nav bars yet for for the sake of being able to navigate this app. I'm going to quickly create a nav bar. So I'm going to go to my layouts application layout inside of the body here. I'm going to create a couple of Ruby tags and a bar of this for simplicity sake. Okay now we have three navigating pages.

So what we're going to do here is we want to take this index and for the sake of organization I'm going to put it underneath. So the index change is where it is on the page. We want to only show our titles on the home page. And the body on the body page. And we want to show everything on our index sites. That is our data flow. So if we want to work with the different data where some places we could test this out? maybe the rail council? We can test it out on the rails console. All right. So we know we have to store of variable here called p and I'm going to set it equal to p = Post.all Just so I have to work with here OK. So I can call P. Dot title. That doesn't like it. It doesn't like it for all of them. So it's going to want it first single but not for all. So if I notice here if I set this equal to b. And I call post dot first we only have one post correct.

We only created one post so now if I do b.title now it works. You can't just call the title on all the blogs you have to iterate over the data. So if we want to show all of our titles it inside of our home page which is where we're saying it's a title page. We need to be able to get down and isolate the level. Does that make sense. So I'm trying to show you guys what the system is asking for. All right. So we're really close that out. And now I'm going to spin up the rails server again so we can see this as we go. We want all the titles so we're going to go into our post controller. I'm going to copy this and I'm going to go into the pages controller and inside a title I'm going to enter @posts = Post.all. But for this case I want to call this @titles = Post.all just so it reads more like what I'm trying to do. My wife was listening in Phantom Of The Opera in the background. Got it.

All right. So titles and now we're going to go to our view page for titles now we have to write a different set of syntaxes if I still have I don't have the ruby tags currently so I want to go somewhere where I can borrow Ruby tags because they're real. They can be irritating to type over time slaking sake. I'm going to just do a couple of these. All right. And so this first one we don't want to show the code because we're going to be iterating over and I called this title titles because I'm doing multiple titles potentially that's part of the naming convention if you're going to work with multiples. You want to work. You tend to want to pluralize if you're going to work with singular then you usually use a singular way a version of the variable.

So I'm going to say @titles.each and the reason I'm not using map is I don't want to create a new array. I want to actually iterate over each item separately I'm not trying to map over or change data and present a new array or say each do and will just say X and then I'm going to call <%= x.title %> and then I'm going to call and. Inside of is a ruby tag. Of course. Now interesting thing here. Most I could show this one but if I have an equals here we're actually going to get a break because it doesn't like showing the action when you go click on it. So we're going to go pull it up here and this is going to break. Now if I get rid of that equals you'll notice this works. And we have my great title.

Now we need a few more titles to make sure this is working. So where would we go to do that other than just writing him in the Terminal One at a time. The seeds file there we go. So it's getting used. Part of the hardest thing with Rails is just getting used to all the different tools you have and then when to use them so I'm ten times do and I'm going to say post and I'm going to run the post.create Now if you're wondering where I'm getting this from. I'm going to scroll back up and my terminal to back to where when we created our first post. This is just a copy of what you type in the database. So I could actually go copy this and bring this in here. And then just do some spacing. Well I see. Can't have a space here but. So now I do. Title body. And then. And. So parentheses. And then I have. The end.

large

This should work just fine so let's give that a test. We're going to go see if our seeds file will work. Obviously they're all going to be the same title right now. I'm not too worried about that. I'm just worried I just want to make sure that we're passing our data correctly. So we're gonna do a puts "10 posts ten created. Now if this was a form first say collecting user information or submitted user data I would say 10 forms filled out or something it's the same effect you always have to work with posts or blog is just easier to for terminology reasons to do that.

So you say rails db:seed which is going to run our seed's file and can post creates that should have been created but I'm not going to run it again. And now we're going to do the rails s and we have migrate title. Obviously that does not look very appealing. So just for the sake of having them on new lines I'm just going to throw a p tag around here just for clarity's sake. And now we have my great title 10 times.

large

All right. So if this is how we brought our database to our home page or titles Page what are we going to do to get the information to our body page. Well we have the email because our generator gave us that because it did a control generator but correct. We need html we need a place to go. And we will need to iterate over the posts. Right. We're going to need to iterate over the post so we need the same data to now be available to the body. But what's a better. Instance variable to use so bodies could work.

Now this naming again doesn't rule it's not supercritical because this is one that you could call anything you just like to leave we like to call it plural because we're dealing with all we're going to go back to the body we're using see I'm going to this in here so I have it. I'm going back to my title and I'm going to steal this whole thing. And that is the only thing I need to change their in order to have what I want. But what did I mess up here. We got to call the body. I need to call the body.

large

There we go. So we have now successfully transferred data to completely different pages different controllers. We only have the one model but we're passing the data all the way through. So and I saw today that you guys finished on custom scopes yes. Yes. I was going to do that this evening but I'm actually going to do that tomorrow when we're in class because that's a perfect place to stop because that's where you can really do some fun database stuff so I'm going to skip over that for this evening. And we're to cover that in class when I get there tomorrow morning which I will be by the way. Any questions about this data flow or anything like that.

So for the index page you would have to make another site that we did create that one we had to create down because we created our Controller by hand. That was at the beginning at the beginning and then we would ruby tags. dot Title and body. So we were still dot each because remember we have to break each one down in order to access it. So we're going to dot each do. Pass in a bar and again this could be anything we could make this. M But you're correct if we wanted to display those on both pages you need a line calling a title on a line calling the body correct.

So we're going to do an end. And this is going to be a title and this is going to be dot body. We are going to do the ruby tags. And end. Can you explain real quick why it's only those outer Ruby erb lines that do not have that equal sign. Or is that something on a cover letter. No that's absolutely fine. The equal sign is Rubys erb way. Let me clarify that in Ruby erb way of saying what code you want to show to the user. So here you see we have all the code. If I get rid of the equals all of all our titles will go away. It's still running the code in the background but we're not showing it to the user. So to make that even more clear because this can be the creation of some really weird bugs I'm going to go ahead and put another p tag on here just so things are broken up. We'll put a p tag on this one as well. And I will close this one as well.

So this way we can see these are broken up correct. Now if this has an equals not only will we have that we'll also get this and this is the ruby logic behind the scenes of the actual iteration over each item. Interesting. So that's what the DOT each actually looks like. If you tried to break it into Html. That's how a html interprets that Ruby logic. So for that reason we want that to run but we want to run it silently behind the scenes. Got it. That's better. That was hurting my eyes. I'm okay with certain amount of ugly. That was just hurting my eyes. OK. Any other questions on data flow or any of that. This is very simple data flow but it gives you the idea of how you can work with the data. Okay. There are no more questions on that. I'm going to close throughout all of these. Now one of the things I wanted to address here.

One of the things that was asked was I asked how to take care of a migration you just want you didn't want. So let's do that let's run another model generator. And we'll call this one. We'll say this one's blog blogs but we only wanted post but we're in a creative anyway and because we made a mistake we're in to do rails db:migrate. Correct. We now have to database tables now really neat thing is if it was the last migration you ran that you made a mistake on. You could actually just do rails db:rollback. And that will actually drop the entire migration. from the schema from everything. It'll pull it from the database it will it will undo the entire last migration. Okay. But only if it was the last migration you ran. That's the risk of rollback. It's also why I don't go into rollback on day one because maybe I've run another migration and that when you want it makes sense.

So you need to be sure that it's the migration that you want. Now another trick with this so let's go ahead and let's recreate that. OK. I will say I mess this up too. It's still textbook instead of body. We called it. Bodey. OK. We messed up we ran this lets see I want. Oh I want to delete that. We're working on it my hold on. Yeah. For the test purposes I want to believe that. So we get the incorrect one created right. Now I could fix this here. Yes. I want to override. And then now I want to say I ran my rails db:migrate. And then I went and checked my schema file and saw that oh crap. OK well let's go fix this here. And then I remember that. Oh I have rails db:rollback right. It makes one think a guess is what might happen if I roll back right now.

So it actually worked. It shouldn't have. It's supposed to break. Maybe that's a new version thing with 5.1 but it used to be if you made a change to this migration file it would. You'd have to reset this migration file back to what it used to be before you saved it in order to successfully roll back. But obviously it successfully rolled back. So ignore everything I said over the last few seconds. And we re migrated and our fix is in place. That is all working perfectly. So now if I need to update this row say I need to add the date and date type rails g migrate add_date_to_blogs date:date. I want to create the migration add date. add date to blogs and it's going to be date and the data type date.

large

And I think I got that right off the bat. We'll make sure here in a second. And this is going to once I run this migration we're going to add this date field to blogs so I'll run rails db:migrate and now we go check our schema you can see our schema now has a date field. That takes in a data type of date. So that's how you can add a new table of all new row to an existing table. Now if we know we roll back we'll remove that and if we roll back a second time we'll remove the entire table. Oh so you can be rolled back multiple times in a row. Correct. But you're going to wipe each successive migration. I see. So you have to be very careful because you don't want to wipe the entire table that you actually need.

Like say we needed the the blogs we wouldn't want to do that. Now I can now I can run on rails db:migrate and I can bring all of that back because as long as these migration files are here it will re seed the schema file once the migration is run. So so long as these migration files are correct when you push to a server like to a live server that's the data that will be populated on the live server. So if you did the rails db:rollback and then deleted that migrate file and then tried to do it again. Will it will be in this anymore? correct. So if I roll back I only have to rollback back once this time because well I have to do both migrations because they also run in order from top to bottom which can be confusing but so I can clear those out and then I can delete these two migration's. And then run rails db:migrate as you can see.

Nothing got updated there now permanently gone. OK. So there's just no way to roll back say your second most recent one. You just have to be very careful delete them back sequentially. Yeah. Yes you want to be very very careful. Say that I did want to go back and I'm in a test database. This is the one. This is the one that I use in class because it's so quick and easy. So let's create blog again. And we'll even keep it with the moody text. Why not. And we'll migrate that. I was like OK I don't like this at all. Quick and dirty way to do it to make sure you get exactly the one you that you want fixed. I can go change this here. And then I'm actually just going to delete the schema rails db:drop. rails db:create. rails db:migrate and that will give me a new schema and it will have the corrected because he didn't delete the migrant files are there correct. They didn't delete the migrate files I just corrected it. I see... But that would drop that would drop any data you hear you had pop up to the database were right. Correct. Or do that outside of development. Yes.

I do that on my own projects when I'm in development and testing because at that point the only data I have is seeds data anyway. So right now my data is all gone. But all I have to do is rails db:seed. And I have all my test data back again. And it doesn't remove any of your. Your view changes that you made if you were to drop your data like that and remake it and repopulate it with the seeds file. nope. Well all that stuff is the same. Looks like. Yeah everything stays exactly the same because the only thing we did was basically scrap and reset our database. So it can be a very powerful tool that's two different ways. All do migration's. If I know it was the last migration I ran that was wrong or Im the last one or two I'll use rollback just because it's a little bit cleaner and it's a bit safer and it doesn't wipe everything. But if I'm not sure what migration it was and I know there's an air that is causing the rest of the app to break and I'm in my test in my test or development environment.

Not my production. Never in my production. I'll do the other one just because it's quick and easy and make sure I'm working with the right data. Would you use a rails db:rollback in an actual production environment. Here's the thing. You're not going to be working on the app while it's in production. You're almost always going to be working on the app. In a development environment. Unless you're debugging in which case there's a whole new slew of procedures. If you're trying to debug live which if you google that you're going to find a million lines about why you don't. So. But yes if you're working with actual client data on an app like if they want you to test the app with client data.

You still wouldn't drop the database you would do just like I did the add row. Here where I created a row. See if I can find it and if I remember correctly I can just change this to remove. I don't do this one often so I may not be right here. And this will give a new migration. You see we have the oh we don't have date in there right now so that's not going to I did things out of order. Hold on rollback. Yes I want to correct that to rails. You spelled Rollback incorrectly. Oh I did. OK. So I roll that back because I don't want that right now. OK. So actually I need to remove this one for the moment. And then I'm going to add in just manually. Date. work with me Andrew. So that's all we had before. Now if I do the rails db:migrate.

Now we have this date field. Now if I run this remove date to blogs. And you can see we have this migration. Now if I did this right on the migrate the schema began with the date on the schema is now gone. Got it. So that's how you would more surgically go in and remove one piece at a time rather than a direct wipe. So if you had to work with your data while it's live. That is what you would do just like you if you were to add it. You would everything would be exactly the same and your rails G migration except in place of ADD you would say remove correct. OK. Rails likes to keep things very very simple. any other questions on that. Okay. So we've covered data flow was when you guys wanted to see anything more on data flow.. All right. So yes I had a quick information from users and organize it we performed that as well because you see we collected the information from the users.

We all have the full form but it's the same principle that we collected all that data and we've organized it into a page for bodies and the page for titles. I added what you wanted out of the taking care of Migration's. Perfect. And then Andrew you had naming conventions. I talked a little bit about the naming conventions. which names are required specifically. Okay that's going to be completely dependent on what you're trying to do and where you're trying to do it. I mean we could spend hours there but a few common ones controller are names and names that have to be very specific. If you create a controller you're going to do a camel case controller. Class name. It has to match what you're trying to access from the model and then your folder for your views has to be an exact match for your controller.

That's how it's going to identify the views that are going to store inside of that folder. That's one place where the naming matters a lot. If you're going to do crud functionality inside of these methods here the crud functionality for post for example for index because we're using resources inside of our routes those are very specific. Those are the index. The new update the show the edit destroy etc. but we can actually call any other method when we're just calling a pages. So even though this is where we did our crud functionality we're going to make a method and we're just going to call this dog. If you haven't notice I use that a lot in my examples. I'm going to go back to are routes and what we're going to do is we're going to create a manual route of get and this would be posts or slash dog

large

and we will create a view inside of posts new file and call this dog.html.erb and then we'll do an H1 tag just so we can see it. And this is our. Page that went to the dogs. Now we can do. Forward slash posts forward slash dog. And I might actually post them I have to run a rake routes to double check that but no there it goes. So this page uses dogs and you see that method name doesn't matter. The only thing that matters is that we call it the same for the page name inside of the correct. Folder for the controller. And we created a route that had access to that name. K ones that you want to avoid. You want to void test I've created test underscore controllers and believe me rails does not like that at all and avoid common Ruby or rails convention names such as string array variable all the the big class names you want to avoid.

But the rest of them will work pretty well and they're pretty much up to your decision. Ok. All right. That answers all the questions that were given. Are there any more questions before I wrap this up. Maybe you don't have to do it right now. Needless to say. Maybe you can like lay out the views and model and controller or page and body page. All of them now and then. Kind of with all of them open at the same time talk about how they connect. oh so open 3 apps and see how the different pages connect. No. No. 3 view pages meant 3 Web pages. No I think so you have like for body you have view. correct. And then you have a model. I mean a title. Do you have something under the model folder for body. No.

The model the only model we have is for database tables so I have the post and the blog which recreated while we were doing the demo. How does the model. Like connect with the view and the controller. So the model connects to the view through the controller. And this is not a database call. This is actually a model call or calling the model and it's communicating with the database and returning all of the data that is stored through that model on the database. So that's where we're getting that information. And this is being passed through to the view. Again does that make a little more sense now. Is your model inside your model is it capitalized P. Is it for that convention. Oh it does. Is that because its a class. That's because it's a class. Any other questions on that or any of that. Good. I've got one quick question. Do you have your routes still open? When you change it to the route you change the slash and pound can you explain that.

So the route is a special command word in Rails saying we want this to be the home page and so we're going to call the verb directly instead of the actual route. So when we're doing the route and when we're doing these this is actually saying take the route which is localhost three thousand and then do forward slash pages forward slash body. You see you see that it's a direct route name. We look over the app on the right. But this is saying basically what we're doing with the pound sign is don't do forward slash actually make this localhost 3000. So you're making the file the the root that right. Correct. So if you do rake routes here. All right. So these are the uri patterns correct. When we're doing a get call because you can see the verb here. We're actually building out the uri pattern when we're doing a route. We don't have a uri pattern because we're the route. So we actually call the full controller action.. So is that navigating into the file structure.

Into the title html file yes it's going through the folder structure to find the file. Its using that as the root. And we can change the root to anything. Obviously we have a problem. Well no actually we won't have a problem here because I'm just too I just won't have access to title right now. So we'll do rails s. And now our home is actually the body as well as the body is the body. You see I have both up simultaneously. I just have to declare them.

So the change from the slash to the pound. Is changing from a url navigation to a file or navigation. essentially there's a little more to it but that's essentially what's happening and this is letting rails know that hey we want this to be the localhost. Now if I leave this is a forward slash we're actually going to get an error that is missing the controller key on the routes definition. So it wants to do. This controller action key in order to provide the route. So that's very specific to the route. Command. Did that help. Perfect. Any other questions. No. All right. Well if there are no more questions then I'm going to stop the recording of this session and well done everyone.