Rails 7: The Demo

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Rails never ceases to amaze.

👍︎︎ 1 👤︎︎ u/FeatureInner3844 📅︎︎ Dec 16 2021 🗫︎ replies

Gonna have a fun time teaching this to students.

👍︎︎ 1 👤︎︎ u/Intelligent-Bath8623 📅︎︎ Dec 16 2021 🗫︎ replies

Keep up the good work, David.

👍︎︎ 1 👤︎︎ u/No_Feedback5169 📅︎︎ Dec 16 2021 🗫︎ replies

That vid makes me want to dust off rails and build something

👍︎︎ 1 👤︎︎ u/FurryLarper69 📅︎︎ Dec 16 2021 🗫︎ replies
Captions
Welcome to Ruby on Rails we're going to build  a demo blog to demonstrate how to get started   with the framework build something real and then  deploy to production let's go going to start with   the creation of the rail skeleton this includes  all the default directories and some stock files   for you to fill in with all your content and it  also sets up all the dependencies that the rails   framework uses by default now that we have this  skeleton we can start by generating the first   model for our blog a post model that's going  to have a string as a title and a text field   as content we're using this generator to create  the files needed for the controller for the post   model for the views for everything  let's have a look at what's been created   the first thing we're going to have a look at  is the migration the migration is what sets   up the database table and as you can see here we  designated that we want a string title and a text   content and then by default rails also adds a set  of timestamps for created at and updated ad this   is then connected to the post model that will  instantiate and encapsulate these database rows   which again is invoked by the posts controller  it has all the actions needed to encapsulate a   rest style approach to developing web applications  you have the seven default actions and a handful   of these actions then have templates like index  show new and edit i could show you one of those   and that is basically all we need  to get started with the most basic   uh outline of a web application so we will run  the migration as the first thing to set up the   database and set up the post table and then we can  have a look at that schema that's been generated   for us as you can see now it just has the post  table in there let's have a look at how that looks   in the browser so we start the rails server and  then we jump over to the browser and as you can   see here it just gives us a nice boot screen  that shows the version of rails that we're using   and the version of ruby but our new app that we  created with the scaffold lives under slash posts   it is the basic crud app hello world we create a  new post first post and when we post that it'll   go to the create action which will redirect to  the show action and then we can go back to the   index action i've done this demo a bunch of  times before and it's always looked like this   it's not very nice so for this demo i'm going  to pop in the simple css framework straight off   the cdn so system we can have something slightly  nicer to look at and i'll do that by going to the   default layout that all the views are rendered  within and i'm just going to pop in the symbol css   styles and then let's have a look if that  doesn't look a little better it sure does okay   so now we have the crot actions not just  for html but actually also for a json api   if i do json behind the post here you'll see the  entire collection currently consisting just of one   element returned as json that you could hook up  to a single page application exposes a public api   whatever you want if we jump back and take a  quick look here at the controller you can see that   this is all mapped up and for these actions that  create an update we have different paths whether   you are submitting from html or whether you're  submitting from json okay let's actually start   developing our domain model so the  first thing we could do is we could add   validations to the post we could say validates  presence of title and now if we go to   attempt to make a new post that has no title  we will get an error that simply says this   can't be saved because the title can't  be blank that error is generated by the the form html that we have the template  here we have under app views posts form   and see if there are any errors it'll show all  these errors first and you can trace that all   the way through from the create as we go through  the create action we tried first to save if that   is successful then find the post that's created  and redirect if it's not successful we will   render the new action again as an unpossible  entity with those error messages in there   that is a user error if you will we can also  make a programmer error here and see what that   looks like if we reference the wrong variable  and then try to load it we can see we get this   error screen in development that shows the  exception being raised and the back trace where   it's coming from and then we actually also have  a console built right into the error screen that   lets you manipulate and look at all the variables  that have been assigned in there now that console   is also accessible um from the command line we  can jump in and start a brand new console here   and interact with the main model that we've been  building up if we go to first post first it'll   fetch the first post that we created this was the  one we created through the web interface but we   can create a another one through this console as  well if we do title from the console content nice   we'll see you start a transaction insert into  the posts table and there we have it another   post object we can also create these objects for  example just post all will get us everything if   we want to find just some of it we can for example  query on created ad we could do time now all day   that'll create a range for the entire day we'll  see we find still the same two posts you can see   what that sql statement actually looks like in  total we can try one where we don't find anything   time now yesterday didn't have anything posted  then that's the sequel for it and this is the   empty array that's returning back okay great  but having a blog that simply just accepts   content as plain text is a little boring so you  use another set of rails features um this is   action text we're going to add to get what you  see is what you get editing for our new blog   we'll start here by adding the action text  elements rails action text install we'll add   a little bit of javascript that we need it'll  add some css for the new editor and it'll add   a set of migrations for us to upload and store  files using active storage in this example we're   just storing locally when you deploy to production  you can store on s3 or other cloud storage setups   it also adds an image image processing gems  so we can make variants of the files that we   upload so that we can get smaller versions of the  images or otherwise so we'll bundle to get that   image processing gem on there and then  we'll run railsdb migrate to pick up the   couple of migrations we have now we have to set  up the model to say that we're going to use this rich text setup and do has rich text content  and then if we jump to the form for that   instead of having a text area we  can add it as a rich text area   now we just have to restart the server because  we added a new gem and then we can jump over and   see what our new posts look like oh we left the  error in there gotta pick that out again let's   do that and then reload great now you see that  the content is not just the plain text field   this is rich we can use rich text we can do  the various forms of markups we have in here   and we can even do file uploads so file  uploads can simply be dragged and dropped into   our editor here it'll upload it in  the background via active storage   to either local as we're doing here in development  or with direct upload to cloud storage but we're   just going to do it here rails logo and then  we create the post great so now we have a post   it has an image attached and if we  go back to all the posts we can see   both of the posts that we've put in there let me  show you how the javascript for that is set up   rails by default uses something called import  maps which allows us to use advanced javascript   without having node installed on  our system we're simply using the   javascript as text and serving through the  browser and using esm to to deliver that   this is set up in terms of what we can use in  our map or in our app as this import map um   the default is this stuff up here rails ships with  hot wire by default turned on that means the turbo   framework and the stimulus framework is already  set up and ready to use and then when we ran the   action text installed generator it also added the  tricks and action text pins and as you can see   here the application.js then imports tricks and  action text and that is what makes those available   to our application so that we can use it but what  if we wanted to add some other javascript from npm   let's have a look at that we will add a piece  of javascript for localizing the timestamps   that these posts were created on our blog both  localizing and using time ago setups so we will   use the bin stop import map and we will pin local  time it will fetch that off npm figure out which   url it should use based off the default cdn that  we're using for this javascript that is jspm   i'll show you later how you can also download  that but we're just going to depend on the cdn   at this time so now we've added  local time to our import map   let's see it right here now we can also  import it and start using it as part of our   application.js we'll import local time from  local time and then we'll start that local   time now we can use this have a look at the post  here we will pop in a new bit where we can have a   posted and then have a time tag and  this time tag will generate an html   time tag which the local time javascript  will identify look at the data local   attribute it says time it goes it'll convert that  utc time into time ago and that's all done in the   in the browser which means it's cache  safe which is a lovely way to present time   so let's have a look at that jump here to the  browser post it ten minutes ago posted six   minutes ago three minutes ago so this is all using  npm directly it does not require node of any kind   does not require npm installed on your local  machine this is all running off a api using jsp m   the cdn but you could also just add these pins to  your application yourself wherever you want them   they can be off your own cdn setup or it can be  off any of the other cdns that are out there like   js deliver but we could also download this local  time instead of having it as a cdn dependency   let's do that um we'll download it instead and  as you can see here it's going to download it   to vendor javascript local time js and when we  jump back into see there we can see that that pin   is automatically mapped there we just  get a little comment of which version   that we're using and if we jump over  to the browser it works just the same great so now our little blog has posts  with localized times has a way to use   a trix editor to use what you see is what you  get but we would also like to add some comments   to this because that'll allow us to show the  relationship within a domain model between   multiple models at once so we'll go back to the  terminal here and use our generator again instead   of rails generate we can also just do rails g and  instead of a scaffold we'll do a resource which   adds just a thinner wrapper around the model  that we're adding here we're going to add a   comment and that comet is simply going  to have a post references which creates   a foreign key setup and a dependency in the model  that this belongs to the post and it's also going   to have a content that's also just going to  be text as you can see it creates another migration and you can have a look at that quite  similar you see it sets up the reference it will   create a foreign key for that reference it becomes  the post underscore id and then it has a text   column for the content for us to use so let's  run that migration and have a look at the main   model that we've just created rails console will  find the first post and that post has comments oh it doesn't have comments yet because we have  not yet connected um as you can see here the   comment model belongs to the post but we also  need to tell the post that the post has many   comments now if we pop back into the console  here we can actually just reload in line and   voila updates to the main model live there are no  comments right now so let's create the first one   it's going to have content of first comment  there we go now we have a post in the system   that has comments but we don't have any way  of seeing that in our web ui so let's add that   to the web ui jumping back in here and then going  to um the post we're just going to have it on the   show template on the show template here  we're going to render all the comments   we'll actually do a partial  for it that'll be post slash   comments we'll pass in instant variable  of postsystem we just use local variables   and let's do comments here and i've  pre-baked some html that we can just pop in there we go so this will render all the  comments that belong to this post this   is shorthand for what you see up here we're  going to render the partial of comments comment   with a collection of posts so it iterates over  those and then we will also render a new form   so let's create those partials  first we create the comment one and i'm also just going to pop that in it's just  going to be a basic div that has an id which we   will later use for live updating of stuff it has  the comment content and we're using that time tag   again with um a time ago to see when the comments  were posted and we're also going to create a um   partial for the new form so that we can create new  comments on our post as you can see here we use   a helper called form width it uses the model then  we pass into it actually we're going gonna pass in   local variable here um and the comment and um  and there we go and then actually let's also   pop in a little notice on the comment itself or  on the post itself just a counter to show how   many comments were uh posted on that we use one of  those helpers pure lies pluralize that will go one   comment to comments and you'll see that in the ui  in just a second here although we also actually   need to add the comments controller it starts out  as just this empty shell here in order to be able   to create any comments we need a create action  we're going to set that up with some prepaid here   before any of the actions are loaded we run  a callback called setpost that will plug out   the post id from the url since we know which post  that these comments are supposed to be created for   it will then take the parameters from the form  and their scope by comment it'll require that   which means that if the comment scope is not  present it'll erase an exemption exception   telling us that and then will only permit a allow  list of attributes in this case just content   says that you can't sneak anything  else in you can't set a different   foreign key or id and corrupt the system this is  just one of those security benefits that you have   in rails out of the box great let's have  a look and see what that looks like we   are now on post we'll go to this post  and see we are missing the route that   post comment is supposed to look up and that's  because we i forgot to edit the routes file   so the resources generator adds this comments  uh resources but it's of course at the root   and what we want it is to have it nested  such that the comments belong to the post   great see there are zero comments so far but  we have our um form down here let's do let's do   one comment we'll create that comment  and there we go we have our comment   and have a quick look at the console for  the the log for this you see here we do   started a post against posts slash three slash  comments this is the nested route that we have   here are the parameters it's using an authenticity  token to make sure that we don't have any csrf   exploits and as you can see here it's even  filtered just it doesn't show up in the log   we also filter other things like passwords and  stuff that you shouldn't be putting into your   logs and then you could see the parameters um  this was the required scope comment and it just   has one attribute that is going to be the content  and what that content actually is then here you   can see setpost is calling um that id the three  from up here it looks it up since we have the   post it proceeds then inserts the comments and  when it's done it redirects to post number three   and that renders everything again so now we have  a blog that has posts and those posts can have   comments but let's add another feature of  rails let's add a mailer such that when a new   comment is posted the owner of the blog gets a  email letting the person know that a new comment   has been posted so we use another generator  for a mailer here um and that mail is going   to be called the comments mailer and it's just  going to have one action on it called submitted   you see this generator of course does not  generate any migrations just a bunch of   files for us to play with so first thing we're  going to edit is the comments mailer and you   can see it's just a stub here we're going to  be passing in the comment that we want to let   the owner know about we're going to  assign that to an instant variable   such that it's available in the view we're  going to mail that to let's say the blog   owner at example.com and we're going  to set a subject for this email to be   new comment then we can edit the templates that go  with this comment mailer that forms the content of   the email that's going to be sent out so that's  going to be submitted html i have one that's   pre-baked we can just pop in and the neat thing  here you can see is we're reusing the same partial   templates the comments comment template the html  template for the html part of the email as well   this is how a lot of things in rails work  that you can use the same templates across   things like emails the first render live  updates you're never recreating templates   more than once and then of course we also have  the plain text version of the email where we're   not going to use that partial we're just going  to pop it in as plain text rails has this newest   feature a neat feature where we can actually  see what these emails are going to look like   we are going to use one of these previews  and it's going to just preview whatever   the first comment is and we can jump to this  url in a browser to see what that looks like   you got a new comment on hello world first comment  that's the html version here's the plain text   version and now we know that the mailer itself  works let's hook the mailer up to our flow such   that when a new comment is created we will also  send out the email so we have the comments mailer   it has the submitted action we're going to pass in  the comment that is being created in this action and then we're going to deliver later deliver  later we'll use a asynchronous job queue such that   neither the rendering of the html for this  mailer nor the delivery of the email itself   happens in line it happens asynchronously  much faster response time in the ui   and that's pretty neat so let's um see  if that actually works we'll jump over to   the browser again jump back to our  post and then send a comment via email   create that comment and we can see whether it's  been sent by checking the log scrolling back here   and you can see the email is being sent it's  being sent to blog owner it has that subject   of new comment it's rendering a mime part for  the html and my part for the clear text and   if you look up here you can see the deliver  later is set up as an action mailer delivery   job which is this out-of-band asynchronous setup  in production we would use a full queuing system   rescue or something else like that in development  it is just happening in line great now we have a   blog that can also send email let's make this  blog live and we're going to use the default   wire stack or at least one part of it the turbo  part of it to make adding comments a live event   and it is surprisingly simple as you saw before  when we looked at the application js hotwire is   already configured in a new rails app so we  can simply start using it so we're going to   start using it by setting up a subscription to  a turbo stream on the post um show action we're   going to use this turbo stream from and then the  name of the stream we're going to use is going   to be derived from the post um since it has an  exclusive stream for the comments that are posted   is that and then when a comment is created we're  going to let it broadcast um to the post that will   broadcast both uh creates updates and destroys  which we can now demonstrate so let's jump over to   our browser and then let's actually make another  browser such that we can have them side by side   and see that this stuff is happening live okay  let's scroll down here is this a live comment it sure is it showed up over here as well  because via web sockets we're delivering   all these updates that are made to  the comments they're being broadcast   whether they're being invoked from a web ui is  here or if they're being invoked from the console   as well since it just goes through the rails  domain model so we could do here find the post   3 and then look at the comments we have those  comments we could take a look at the last one   and what would happen if we destroyed last  one boom it's gone and it's gone because   when we destroy the last one a callback is  being triggered by that setup of broadcast 2   that will broadcast this turbostream element  remove and the target is comment underscore id   which matches the dom id we had set up for the  partial for the individual comment we can also   update here from the console so if we do a update  of the content content uh updated from console you   can see that that update is sent out as well that  update contrary to the delete update is actually   done asynchronously because we're rendering  a template so that also happens out of band   and there you have it creates updates and deletes  are all broadcast automatically and of course you   can tweak this and set it up to your heart consent  but simply adding the broadcast to will do it for   all the three actions by default when you follow  the conventions okay we've created quite a lot   of code let's have a look and see if we also have  some tests and of course we do because all these   generators we've been running have been creating  stop testing that actually exercises the app   and if we run those with rails test we'll see a  couple of them failing we have one failing because   of a invalid foreign key and that happens  when we go to destroy the post then you have   comments that depend on that post now having  an invalid foreign key so we can fix that first   by jumping back into the post model and instead of  just saying has many comments we'll also say that   they are dependent and they will be destroyed when  we destroy a post then let's run the tests again   now that test is no longer failing we still  have a failing test for the comments mailer   because that is of course just generated off   the defaults that weren't tweaked we'll use um a  fixture here if you have a look at com gml you'll   see we set up fixtures for all models that are  generated through the generators such that you can   set up a set of fixtures that you can refer to  in your text in your tests that run very fast   and then i also remember we changed the subject  to new comment and then we sent this to the blog   owner and it was from example we're not  going to match on the body right now   let's go back and run that boom all our  tests are passing on our new wonderful blog   that does what you see is what you get  editing it does comments it does live comments   and now our application as such is is done  but what if we wanted to show other people   this application let's deploy this to production  and i'm going to use heroku to do this because   heroku is nice and simple and easy to use but  where the rail skeleton by default is started   with sql lite as the database heroku uses  postgres but thankfully there is a command here   railsdb system change where we can change  the configuration of our database to use postgres instead that will add the postgres  adapter so we'll have to bundle for that   and then we can add um everything to  git because that is how we will push   to heroku so we'll add everything to git we will  commit everything that we've added as first here   and then we will create the heroku setup  that we're going to deploy our app to   and once we've done that we can push  our app straight to heroku heroku   main and we're going to get a little error  here in just a second that we can correct   because there is a check here and you can see this  is failing because i'm making this demo on an m1   machine and heroku is not running on an arm64 so  we just have to add x64 here as our platform for   the bundle lock we'll do that and then we'll  add the um gem file lock again commit that added the platform and then we can push again and now we have deployed our app to heroku  we've been assigned the mighty tundra   as our url for this and we can go have  a look at that in just a second we need   to do a couple more things we need to first of all   migrate our database which will also set  it up or we use heroku run rake db migrate and then we need to add redis  as an add-on to our heroku setup   because red is is used by the turbo setup  to send those live updates back and forth   great now everything should be setting up so let's  have a look at our live app deployed in production i can use this one here and you see the page  you're looking for doesn't exist and that's   because we haven't actually set up a root route  in our application so let's do that if we go back   to the routes here you'll see there's actually  a comment just for that purpose so we'll set it   up so when you go to the root it'll go straight  to the posts index and we will commit that setup we'll add it and commit it adding the root  route and then we can push that again to heroku now that's set up so let's have a look  and see if the app works in production   there we go we have an empty one of course because  it's a brand new database this is the first post now the only thing that does not work yet  here in production is drag and dropping   files because heroku would require us to set up  s3 and you can use that as an exercise for the   reader for you to set that up but it is quite  easy to do just a matter of a little bit of   configuration and then you will also have  the direct uploads with drag and drop here   but let's create this post and  then let's create the first comment and check that everything is working here in  production and there you go there is now one   comment posted so let's do the test and see  if we're set up and it works correctly with   the turbo back to get the comments from one  side to the other this is the second comment and it sure does so now we have the entire  application running in production backed by   a live setup that uses redis  and all the other goodies   and that's all you need to get going get  started building something real with ruby   on rails taking it all the way from hello world  to who knows perhaps maybe one day ipo thank you
Info
Channel: David Heinemeier Hansson
Views: 1,181
Rating: undefined out of 5
Keywords:
Id: mpWFrUwAN88
Channel Id: undefined
Length: 34min 14sec (2054 seconds)
Published: Wed Dec 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.