Let’s build Reddit. Well, maybe a very junior version of it called micro-reddit. In this project, you’ll build the data structures necessary to support link submissions and commenting. We won’t build a front end for it because we don’t need to… you can use the Rails console to play around with models without the overhead of making HTTP requests and involving controllers or views.
Disclaimer: This is my implementation of the Micro-Reddit project from the Odin Curriculum. I'm not a Rails expert, so do not take this walkthrough as gospel. If you see any errors or something that is incorrect, please feel free to contact me in the comments.
Create a basic Rails app. Rails does all the heavy lifting. All you have to do is run
the rails new <project name> command from your terminal, which creates a basic Rails directory structure with everything you need to run a simple app.
From the command line, run:
And you should see:
After you create new direcotry, change into that directory from the command line:
Step 2: Create a User Model
From the command line:
The rails generate script creates templates for models, controllers, and views. In this case, we will generate a new model, and name it User.
The additional arguments username:string, email:string, and password:string create 3 columns and sets their data type to string.
After you create the User Model, you should see this in your terminal:
Check the micro-reddit/db/migrate/ folder to confirm migration file was created. It should look like this:
From the command line, run:
The rake db:migrate command should create a sql database in your micro-reddit/db folder.
Working with the Model in the Console
From command line:
Check User Table; it should be empty:
Create a new User record:
Check if record is valid:
It’s currently valid because we have no validations. We don’t want to accidently create blank usernames, so we can create validations in the app/models/user.rb file:
Reload the console, and confirm validations are working:
If you can’t save record to database, it is good to check error messages with #errors.full_messages method:
Finally, create a user and save to User table:
Step 3: Create a Post Model
Generate new model Post:
Code above generates Post model with title: and body: columns.
Migrate table to database:
Add some validations to app/models/post.rb:
Confirm that you can create and save a post in the console:
Run rails console if you haven’t already.
Step 4: Build Associations between User and Post Models
Generate Migration to Add Foreign Key to Post Model.
The user:references argument will add a column with foreign key that references User model.
Check db/migrate folder to see new migration file:
Run migration:
Create relationships in app/models/post.rb and app/models/user.rb:
The above code creates the relationship between Post and User models. It basically says a post belongs to a user, and a user can have many posts. This is known as a one-to-many relationship.
Goign forward, you will likely see the belongs_to and has_many helper methods a lot when building models in Rails.
###Confirm associations in console:
First, create a new user,
Now create new post referencing new user. Add the user_id from previously created user. In the above example, the user id is 5.
Confirm you can find posts for given user:
Finally, confirm you can find User for given post (the other side of the relationship):
Step 5: Build Comment Model
Generate a Comment Model:
Running the above command will create a migration file located in db/migration folder. See below:
Run migration:
##Step 6: Building Additional Associations
In the app/models folder, update associations for each of the models:
##Step 7: Add Validations to Comment Model
We’re adding validations to the Comment model, so we don’t accidentally create comments with no associated User or Post.
In the file app/models/comment.rb, include validations:
By validating :user and :post, we validate based on associated objects. Another way is to validate
using the foreign keys: :user_id and post_id, but I’ve read this is not as robust as the above validations.
Validating :user and :post will check that associated object exists, while validating on foreign key will only check that a key was entered, but not whether that :user_id or :post_id actually exist in the other models.
Let’s test in the console:
First, I create a new comment with :body argument and try to save. I cannot save, lets check the errors.full_messages.
Next, add auser_id and post_id to your comment. They need to already exist in your User and Post models:
It looks like it is now a valid comment. Also check to make sure you cannot create a comment with invalid user_id and post_id.
Lastly, check to see if you can find comments from User and Post objects:
##Step 8: Check valid associations in Console
This is a final run-through to make sure the associations between the User, Post, and Comment models are working as we expect.
My tables should be different than yours, so play around with your sample data and make sure you can return similar results: