BUILD A REDDIT CLONE - RUBY ON RAILS TUTORIAL

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we will be building a clone of Reddit so we will be taking the core features of Reddit and try to build this in Ruby on Rails and before we get into the video I want to give a shout out to my sponsor Scout a PM Scout a PM makes it easy to track down bugs in your code and eliminate performance issues and +1 queries and lots of other things so do check that out in the description below i have a link there where you can get a 14-day free trial so looking back at the reddit or calm website we can see there are multiple communities or sub reddits and within each of those communities there are multiple posts which we can upload download comment upon so all of these great features we will be trying to build into our application so let's get into this and set up a new rails application so I'm running rails new to a color app red a clone and this will take a few minutes to install so let's leave this running to handle all the gem downloads that we need for our application so once it's complete we can open up the directory in our code editor and by default rails set up a git repository for us I'm gonna add all the files to the git repo so leave a message to say that we're initializing the repository you so all the files are now committed to get now it's completely optional step but it just helps us to keep all of our files in version control so now I'm going to modify the database file so the file with an config I'm gonna set the database type as postgrads now you can use sequel sequel Lite for this but my preference is generally postgrads because in the production environment I use Postgres and I like to keep the production environment in sync with the dev environment I'm gonna set this up real quick and in our gem file and we are going to add the PG gem for Postgres so I'll just remove the version for now you'll see that in our main directory we have a file called Ruby version ruby version and this is where we identify their version of rate of Ruby that we're using but we can also add a file called ruby gem set and i like to do that because it allows me to separate code base for each of the applications that i build normally when I begin a project I will create a new gem set so I'll do this using Ruby version manager and the reason I like to do that is when we are using the same gem for different projects we may have different versions of that gem that we need based on the version of rails that the project is using or the version of Ruby so it's good to have a separate gem set to isolate that codebase and that's something we haven't really talked about in previous videos just adding it here so you guys know how I approach that so you can actually build a project without using Ruby version manager but it just makes it easier if you're working with multiple applications so our next step I'm going to take is to set up the device gem so device is used for signing in or creating new accounts in our application so let's add the gem to our gem file and now we'll run the bundle install to make sure that gem is installed so now we can run the generate device stole command so this will create the files we need to get device setup correctly so it has given us some instructions here in the terminal so we have to paste this into our environment development file so let's open that up now paste this in now let's go to our routes file and set our default path for our home page you and it is prompting us here to add these notifications to our template but we're gonna leave that for now but we will add this rails generate device command so this will give us our views that we need to be able to edit our signup pages or sign-in pages so we can open up the device file within our config initializers folder and in here we can set up a email address that would be the default sender email so now let's go ahead and create a controller so this will be a public controller for our home page we can just copy this say that the public controller is inheriting from our application controller and we'll add a method in here for the index so let's create a new folder for the views this will be the public folder and we'll create the default view which will be our home page let's call this index.html GRB and we'll add some dummy text here just to get this started and now is run the rails application test this out so at this point we can see that we have not got the database set up yet so let's do that now so let's run rails DB setup and I will create the databases we need and it also tells us here that we need to run rails to be migrated so running the rails TB migrate command will allow us to generate a schema file so that will give us the most recent version of our database stands so can open that up now and we'll see here that there's nothing in here yet and we're at version zero every time we do a migration on our database this version number will increase but if we reload the browser now we should get the updated page and we can see here that our homepage is now working so now we will create our first device model do you see rails generate device will call this model account now you can call this user or whatever name you want here but for me I like to just stick with the same naming convention for multiple applications I usually call most of these device so I normally call the device model accounts so in our so now within our migration file I'm gonna add some additional values in here some additional columns so I'll record the first name last name and user name and we can also add a bio here just some details about that user so this will be a text field you so now let's run this migration to add these fields to our database you and now if we open the schema file we will see that our table has been created now I'm going to go back to our application layout and in here I will include a partial for the header and can also add one for the footer you so I says correct a name and the title so now I will create these partials that we have added to our application create a header and a little bit some dummy text we'll do the same for the footer now once we reload we can see that each of these files are being loaded properly so now let's add good strap to our application so we'll use bootstrap to handle the layouts of our front-end view so bootstrap has been installed using yarn now in our application is under the PACs folder I'm gonna add the required bootstrap to ensure that gets compiled into our JavaScript file so I'm going to test to see if this has been installed correctly so I'll put some dummy code here using bootstrap markup so use the classes from bootstrap just to see if it's loading correctly and we can see here in the browser that it's not splitting it into columns like it should be it is giving an entire row so it looks like the stylesheet has not been added yet so let's add that now and we can paste this in so if you go to the bootstrap installation instructions it will show you what file to include in your stylesheet I'm just gonna paste that in and we will rename this to s CSS so it has to be a sass file not a CSS file but looking at the console here in the browser we can see that we still haven't got jQuery and bootstrap requires jQuery to be installed let's use yarn to add jQuery now you so going back to the browser oh that's pretty load and we'll see that now the error has disappeared so we have jQuery installed and the style sheet for bootstrap is working so let's go ahead and add some actual markup for our header so we'll create a top navigation bar and we'll use the generic markup for bootstrap to do this we'll have a title for the reddit clone and we want to also have a sign in and sign up link so add that to the top bar as well it's crazy Dave and float it to the right and this will be our sign in/sign up buttons you I will use the new account session path and then we'll add some styling to this using the bootstrap classes we'll add the button and the button outline class and this one will be the signup and for this one we need to have a new account registration path now these paths you can get using the rails routes in the terminal so just looking back at the reddit site we will have a two column layout on the Left column will be about eight columns wide and in four columns on the right and we'll also have the trending section at the top so it'll be four columns wide so this is our homepage view the public index view and here on the Left column will be eight columns wide so it with the main area where all the posts are and the right section will be four columns wide so top section will be four columns times three columns adding to a total of twelve columns you so let's just add some dummy data to get this layout right first so this would be the left column that's our main section of the page sidebar will show our communities and of the trending section just above that and it will also add a title here at the top this will say are they heading here choose to say that this is trending content right h2 and when we check this out in the browser it's looking okay so far but we want to add a little bit of padding to top space things out a little bit and we can probably make this trending header smaller too maybe this could be a paragraph and we'll give it a class class of h4 heading for style we'll also have a heading at the top of the main section on the homepage and this one will be popular posts so now we have a very basic layout for the homepage it's very simple right now but just a starting point for us to get something together let's add a little bit of a border to the bottom of this add some padding to the bottom too and then we'll add some margin also just to space the content underneath okay you we can also add some margin to the top of this main section and for this sidebar we can say up-and-coming communities here so this will be communities that have got a lot more members recently and we want to feature them here on the sidebar that's how it is on the main reddit web site so let's try to imitate that so here I want to create a list and I'm going to use the list groups from bootstrap so I think it looks pretty close to what's on the reddit website let's just copy and paste this section and then we will modify it you so I think we can remove this inline style tag it looks pretty okay right now it's it's good enough for us to start with so at the bottom of this list we will add a link to few more communities or view all the communities so let's add some margin to the top of this button to space it from the categories above so now let's begin creating some of the tables we need for our data so let's create a new migration for Communities you so I'll add a name for the community and a URL so now within our migration file let's add the timestamps so when a community is created or when it has been last updated that timestamps we record those automatically for us and we'll also add a integer value for the total members in this community so members will be able to subscribe to the each individual subreddit or community and we can also add a text field value for rules for that community so we may want to add additional columns to this table later but I think this is enough to get us started so let's go ahead and run the rails DB migrate to add this new table to our schema file and now we will just sign up for a new account to test the account creation process by device add some dummy details here so that is created an account and we're actually signed in at the moment but we want to show different buttons here at the top if we're signed in so if we're signed in we want to show a sign out link so let's add a condition here in the header file for this the header partial so we'll say if the account is signed in and if you are using a user instead of the user model instead of an account model that would that helper would be if user signed in but in our case it's account signed in because we called the model account if the user is signed in or the accountant signed in we will have this sign out link so let's set this up now so this would be destroy session earth destroy account session path and the sign-out path uses the delete method the verb is delete so we'll add that and we can check this in their routes so we go to our terminal and type rails routes we can see the path for the sign out link so we have this destroy account station and you'll notice here that the verb is delete so that's why I'm adding that delete into the link so by default links use the get method so the verb will be get but we need to declare it as delete in this particular example so the sign out link has worked and we will sign back in again to test that process so now let's have a look at the communities so we have this section for communities but we did create a migration for that but I do want to add one more thing to the migration so a community is created by one of the members so we want to record the member or the account creates a community as they will be able to edit it later such as the name the description so well add the roll back our migration first and we'll add a reference to the account model let's go back to our migration we'll add a new column here for references and it will reference the account then we'll run a migration once more now we will set up a new controller for the communities the communities controller will inherit from the application controller and we'll create some methods in here grain index method we'll create a show method once someone clicks on that community also have a great method and a new method for some of the methods in this controller we want to limit the access to them so we want to make sure that the user is signed in at the very least so this authenticate account elaborate gets called by default on all of the methods and this controller but we can list exceptions by passing a parameter for that you so now let's create our views for the communities create a folder called communities and we will add a index file will also add a new HTML file and we will have a form so the farm will be for creating new communities and we'll have a show view to list all of the posts in that community so now we will go ahead and create new model for the community call it community dot RB and this will be a class with the first letter capitalised ruby we capitalize the first letter of classes so we'll have in here it belongs to account and we will validate some fields or validate the presence of the URL the community name and the bio of that community so just to make sure these fields are present before the model actually saves so in the communities controller now we will load the communities in the index method so we go back to the index view in the communities views folder we'll iterate over the communities and output the name of the community so this helped put the community dot name we'll copy that and we will also output the bio I will use a simple format helper to output this as paragraph so we'll wrap our community name and a heading tag and we can enclose all of this inside a div so we'll also need to add the communities within the routes file so we'll use the resources command to do that so resources will create all of the default routes for us such as the create new show and delete methods so automatically creates routes for us so we'll check our routes now using the rake routes command and you can see all the new routes are available to us so let's add a link to this heading tag for the community name we'll add the path so I'll get the community as we'll also add a link then to the view all communities on our index or our home page view let's try this out and we're getting an error here saying that the community's value is not being set so this instance variable is not being set right now let's have a look into why this is happening and here we've got communities equals community dot all so I'm going to wrap a conditional statement around this block of code we're gonna say the we're gonna say if the community dot size is greater than zero so if there are any communities will execute this code and then otherwise we will output a message to the browser saying there are no communities to display so let's go back to our controller now you can see that we're loading from this community model I have a look at the model see if we can spot anything and it looks like we have forgotten to add the inheritance from the application record in our model Alice doesn't seem to be solving the problem itself now it was a mistake that we made before we missed having that inheritance but there is still another issue but for now we'll keep going we'll add a new view for creating a new entry maybe it will shed some light on where we went wrong so we're creating a partial or loading the form and we'll just go directly let URL let's see what's happening here go to our form view and we'll input a new form here say forum for and this will be for the community instance variable and we'll add a value for this forum helper so I'll call this form Emma close is using the end tag so this adds some fields to this form so let's add a label for the name and we'll add a field to capture this name value a form dot text field name and we'll add a class from good straps we'll use a form control class and this wrap this in it is so we'll add the class form group let's try this out we're still getting a problem here for the community loading of the community so this had this into our controller see if this solves it so it's still returning a nil value every time we try to load this community model and it looks like we've made it naming mistake here to one of our callback methods so this should be B this should be B for action and then it runs the authenticate account so now we're getting the no communities to displays we haven't got any communities entered into our database yet so that does sound better than what we were getting before so let's go back to our view now so at the top of this file we're going to check to see if the user is signed in and if they are signed in we'll give them the option to create a new community so you'll say create new community and then we'll pass in the new community path along with the classes from bootstrap so we're gonna use the button class and we will create a blue outline around this button so this is not gonna be a button that you will use frequently so I think we can use the outline to stylus so it's not right in our face so let's test this out so I'm going to jump back into the application view and we'll add a container and a row to this view but move the yield up inside of this content we can add a column here too to fill the rule this will be column small 12 so I'll fill the entire width of this row so this is just some markup from bootstrap to give the layout some structure now let's click this link and we've got a new community form but there is no fields showing right now let's go back to our farm view so let's add a submit field onto this form just to see if we can see on the front-end you and again we're not seeing it but the reason for that is that we forgot to include the equal sign at the top of this file so I need to output the form tag so if you don't have the equal sign nothing within this block of code will load so it's very easy to make these mistakes so you have to be very careful so this add some markup to this to wrap around this so you want to make the form only half the width of the window it's very large fields right now so that's a little bit better so I'm gonna duplicate this code create some additional fields let's add the URL we can also add in the bio so make this a text area tag instead of a text field will change the label name also so let's test this out and if we look on our server logs it looks like we have an error here for the word bio the field bio so I think we've maybe a mixed up somewhere along the way so we look back at the schema to see how things look and in our communities we don't have a bio field so we have a rules field let's change this so I think we have a bio field on the account model not on the communities model okay so that's working now got the rules got the URL name so let's write the code for this create method so before we do that we want to set strong params so we will populate the values using this method so we'll say params don't require I'm gonna require the community and then will permit the name URL and the rules that's the values that we are allowing to be passed from the browser so then within the create method we will set up a new instance variable called community so this will load a new model instance community don't you and it will pull the values based on these parameters thing using the method at the bottom of this file and then we will and then we will run the community save and if it saves and we will redirect the user back to the community's path if it doesn't save then we will render the new method again so that will be that form that they were at previously so will populate the values they are salty how they can make the correction if there's some mistake in the form that they filled out so before we do that we will also save the account ID based on the current user that is signed in that's a current account in this case I will use the ID value from that so as test is out now so create a new community called web dev and they will create a URL and some basic rules for the community so we look at a server log we can see there is a problem saving this file but saying that undefined method bio again we have a mistake in our model so we can remove this field so we're validating the presence of the rules instead it's really the page and see what happens and we check our server log it looks like it is saving the value this time but in our show view there is also a reference to this bio let's go back and fix this in the show view and we'll get this thing working so this time everything appears to be working we have our new community so now let's set up our show view so that we can actually click on this community and get some details about it first let's create a method to load the community that we are clicking on so in this case we will use the find method on that community to load that community by the ID that gets passed in so we will be calling this method from the before action filter and we want to use this for the show view so when we click on this new community link we don't get any details right now so we have to add values to the show view let's go back to our views or the community open up the show view and will output basic details about this community so output the name and we will also output the rules and we can use simple format to add the proper paragraph tags and layout for this littlez value so one thing to note here is there's no way to go back to the homepage right now so let's add a link to go back to the homepage so back to our header file and this red a clone text will turn into a link I will go back to the root path once we click on this now back to the home page and now on the right side we will modify this list of communities so I'll just put in the new communities so I can copy this from the communities controller and just paste it in and we'll limit this to five communities so I know at the moment we only have one community on task community but limit this to five so that once we add more it will only be pulling in five communities here and we'll iterate over these communities and output a name I'll put the name as part of this list as delete some of these entries will add the community name so let's reload the browser and we can see the new community has been added so there's add a link to this so this link will point to the community path also need to pass in the community variable click on it now we get directly to that community so that's good so next let's look at creating posts to post will be long inside community so let's create a new migration for this so let's add a title which will be a string and the post will also have a body so this would be a text along a text field and we can start with this for now let's open up our migration file and in here we can also add the references we want to post to belong to an account we also wanted to belong to a community and then we will also add the total uploads or that post will also keep a record of down votes and finally we will add the timestamps one other thing we can add here actually is the total comments on this post so now let's run this migration I will create a new model for the post the post will Herot from the application record we will validate title field the body field and the account ID and also the community ID these are the values of want to ensure exists before a post is created so while we're looking at the validation I just realized that we have forgotten to set some default values for these police total comments down below sub tools so let's roll back and update our migration file so by default I want to have the total comments be set to zero I also want the total uploads and downloads to be zero to begin with so that way we are always guaranteed that it has got a number value just run the migration once again now we will say that the post belongs to an account and it also belongs to a community now we will go back to the community model and we'll say the community has many posts and will also go to the account so our user account will say that the user account has many posts and the user can also have many communities that they have created now I'm going to take the code from the community's controller and I'm gonna copy it and paste it into a new file here we're gonna create a post controller so I'll paste this in we will just remove some of the values and replace it with posts so mostly the basic functionality will be the same here we want to list the ability to list the posts create new posts although the standard procedures here I was gonna find and replace the values replacing the community value with post value and you could actually use the rails generate controller and the terminal to to generate most of this boilerplate code but I think it's pretty quick to just replace it this way so just takes a couple of minutes or replace a code and most of the functionality should be the same here anyway we're just changing the field values the column values that we are allowing to saved you once a user creates a post we will redirect them back to the community in which they create that post for so we can do that using the post dog community ID passing that into the community path so now let's create our views folder for posts and in here we will add entity we'll add our form partial it'll also copy this code from the community forum we'll just modify it so the name will change to title and we have a body for this post we use a text area for the body so let's add a new file for the new post that we create so in this new file we will load the partial for that form we'll also create a new file for the edit it's when you're headed that post so it's gonna be almost the same we're just changing the wording in here and finally we will have a show view for the post so here we are outfit the title to post and we'll also had the post body so we'll use the simple format but the display of that so they adds a correct our graphs so now in a routes file we will add the resources link for the posts so generate all the paths all the routes for that post so the next thing we will do here while we're in the resources is to embed our nest these posts within the communities so a community will contain the posts within it so having the nested routes does mean that we will need to update our views so going back to our posts forum so in here we will have a in here we will have to modify the values for the forum for tag so we'll need to include the community along with the post since we are generating the URL containing both of these parameters so going back to our post controller and a new method we will also need to set the community so we can do that using the params and we will use the community ID from the params and since this is not something we do that often we can check the routes to just to confirm what our path is going to be for each of these posts and we can see here that they are named as new community post so we're combining on the community and the post in the one path so in this case we can see the community ID is embedded in the URL as a parameter so using a parameter here to to load the community as an instance variable what's a community dot find and we'll select it based on the parameter so now let's go back to the show view for our community and here we are going to add a link to create a new post so let's say create new post and the path will be the new community post path and you'll need to pass in two values into this actually we'll just need to pass in the community value so that would be part of the URL so I'll give it a class of button and the button primary and we'll float this link to the right of the page so let's click on the community and see how this looks so as you can see on the right of the page we have this new post button now and at the top of the URL you can see that there is an ID here for the community what happens here if we click on the submit button without letting in without entering any values you can see that it won't be saved because our validation is kicking in but we do have this community ID being set as one of the parameters so it's not within the post parameter but it is set by itself it's part of the URL so we can go back to our controller and in here we will want to populate this community ID in this case we're just taking it from the params we're adding it to the post and the issue were facing here is that if the post is not saved then it is calling this new method loading the form again but the community instance variable that we have here as part of the form is not being said so what we can do to fix this is to copy the community code from above and paste that in here so if the post doesn't save we will load this community SS variable and I will populate the form tag for us so now when we submit the blank tag it will still return the proper form to us so let's test it out with real content now and it looks like it is saved correctly you can see that have been input and we are storing the community ID which is great so now we can load these posts as part of this community so now we're on the community show view so we can output the posts are attached to this community so to do this we will add a or we add some code into the show view for the community we will iterate over the posts for that community you so I say link to post title I'll pass in path so let's wrap this in heading tag and we'll also output the body of the post we want to truncate at Ohlone output some of the post content I'll use a helper for that truncate Alpert and it will wrap this body of the post inside paragraph tag and we should also update our path to include the community and we're also missing the length parameter here for this truncate set pass in length 200 so it would be 200 characters long the body of this post so now within our communities controller for the show view in the communities controller we're going to load the posts based on the community like community the posts and you can see here now that these are output to the browser it's very simple in a minute very basic information being output but just to wrap this video off we are going to include some posts on the home page so we'll pull those in on the home page to to show some of the latest posts that be made on the platform so for this community rules we're probably gonna move that into a sidebar later but for now it's fine just leave it here so let's go back to our public controller and in fact we can output the code for this first in our view so we can actually copy this from our communities show view we wrote this earlier for outputting the posts paste this in and we'll wrap this in a div I'll call this card will give you the classic card so this is a good strap class to give an outline around this div so now finally within our public controller we will load in the latest posts so I'm going to load these posts by order so reverse order by ID then we'll limit this to 20 posts so once we try to load this again if we open up our terminal we can see there is a problem here this code we pasted in looks like one of the values is not set so in this case the community is not set as an instance variable but we can load that from the post-doc community and try to pass it in the community ID just to prevent from having to load that record from the database so I can see that that now works we can click on add to get through to that post so I'm just gonna add a little bit of padding around this post as it doesn't look so great at the moment terms of the design we're gonna add a basic padding around it I'm not gonna do it for this video there will be a part two of the Reta clone where we try to tidy things up and round things off if you've enjoyed this video do make sure to subscribe to the channel for more Ruby on Rails content and if you would like to learn more about securing your Ruby on Rails applications make sure to check out my sponsor for this video Scout a p.m. so they have a service that allows you to track errors in your code and eliminate performance issues and really just make your application more secure in general so check out the link in the description below for a 14-day free trial but other than that I hope you guys have a fantastic day and I will see you all in the next video
Info
Channel: David Battersby
Views: 14,467
Rating: undefined out of 5
Keywords: ruby on rails, rails 6, rails, ruby on rails tutorial, tutorial, web development, web app, ruby, rails app, programming in Ruby, ruby language, web app tutorial, rails tutorial, mvp, website, platform, app, startup, walkthrough, coding challenge, Ruby (Programming Language), learn ruby on rails, coding, live coding, programming, build web app, how to use ruby on rails
Id: aD6JvHKNPPM
Channel Id: undefined
Length: 57min 30sec (3450 seconds)
Published: Tue Jan 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.