What I've learned when building Hackernews Clone
I'm not a fan of Hackernews, but I love how the structure of the website. Hackernews is one of the awesome link aggregator website out there. Same like Reddit. The feature of Hackernews that I love is ;
β nested comments
β simple form π
β the algo for the points system
β the upvote stuff π€
This is the running app
That said, I think of building a Hackernews clone π. I want to improve my Ruby and Rails skills by building it. Rails are great for building MVP tho compare to other frameworks (in my opinion).
Naming app π
For my app name, I called it DSCNEWS. Haha, seems weird right?π. Luckily, I join Google Student Developer Club at university. It's a cool club btw. I learn a lot from other hackers minded people. That's why I name it DSCNEWS (I remove 'g', cuz it's hard to pronounce => gdcsnews).
Build in public π¨π»βπ»
I build this in public because I believe that there have tons of opportunities out there waiting for me. I just need to show it to the world. Since I share my side project with LinkedIn/Twitter, I got a lot of job offers and feedback for my career path. Before this, I'm afraid of building in public too, but I choose to try and walla, the result seems conversely with my initial thought.
Ok2, enough for the introduction. Let's go for the real lesson I've learned.
This is my Final gsdcnews
app
This is a page when the user does not sign up yet;
The Link Page
Page when user Sign in ;
Submit link page ;
Account page ;
1) Migration
I'm new to the Rails community(before this, I'm in Front-end Worldπ). So, the concept of Migration is a little bit hard for me at first. I would say, migration is like ;
a convenient way to alter our database.
This is from the Rails Doc;
You can think of each migration as being a new 'version' of the database. A schema starts off with nothing in it, and each migration modifies it to add or remove tables, columns, or entries. Active Record knows how to update your schema along this timeline, bringing it from whatever point it is in the history to the latest version. Active Record will also update your
db/schema.rb
file to match the up-to-date structure of your database.
In this project, I use migration a lot.
For creating Model
rails generate model Link
Add user_id
to the Link
table
rails generate migration add_user_id_to_links user_id:integer
Remove user_id
from the Comment
table
rails g migration remove_user_id_from_comments user_id:integer
and so on...
When you do a lot of migration, your file will look like this ;
note: Every time you do a migration, your
schema.rb
file will change based on your previous migration or after you dorails db:mirate
command
2) Devise
I love how Devise gems ease my life for implementing authentication π₯.
It handles my user acc management
Sign in/up stuff
Only authenticated users can send links, add comments, upvote/downvote, and so on with its helper function;
before_action :authenticate_user!
I add it to my controller
user_signed_in?
current_user
3) Learn new Gems π
This is a list of my gems for this project
β simple_form
β bootstrap-sass (I use Bootstrap for this project)
β sassc-rails
β jquery-rails
β devise
β acts_as_votable
β will_paginate
4) Use Partial
Think of Partial as a reusable component in React World. We can render it for every stuff that is repeatable. In my project, I use partial on form, navbar and comment. How I do that ??
Ok, take a look at my edit.html.rb
file;
<h1>Edit Links</h1>
<%= simple_form_for @link do |f| %>
<%= f.input :title %>
<%= f.input :url %>
<%= f.button :submit, class: "btn btn-primary"%>
<% end %>
<%= link_to "Back", link_path(@link)%>
and new.html.erb
file ;
<h1>New Link</h1>
<%= simple_form_for @link do |f| %>
<%= f.input :title %>
<%= f.input :url %>
<%= f.button :submit, class: "btn btn-primary"%>
<% end %>
<%= link_to "Back", link_path(@link)%>
seems like something is repeatable π€, yeah, it's a form !!. We can make a partial for it !!
create _form.html.erb
file, then paste the form into it;
<%= simple_form_for @link do |f| %>
<%= f.input :title %>
<%= f.input :url %>
<%= f.button :submit, class: "btn btn-primary"%>
<% end %>
After that, change the edit
and new
file;
<h1>Edit Links</h1>
<%= render "links/form"%> ππ
<br>
<%= link_to "Back", link_path(@link)%>
<h1>New Link</h1>
<%= render "links/form"%> ππ
<br>
<%= link_to "Back", link_path(@link)%>
Cool right π
5) Building Form
I use simple_form for form stuff . It handles all of my forms. If you wanna learn more, go check out that gem.
6) Use Controller Betterπ
The term Controller itself is new to me. I know it from the MVC paradigm. It is a way to control the Model and Views. I would say, like a middleman πββοΈ between the Databaseπ¦ and the UIπ. When using Controller, you will need to think π§ of the routing in routes.rb
, your Model in db
file, and how to interact with the Views file(quite confusing at me firstπ
).
Also for auth stuff, you also need to put it in a Controller file. For example ;
class CommentsController < ApplicationController
before_action :authenticate_user!
end
you want only authenticated users to comments.
All the Create, Read, Update and Destroy (CRUD) stuff will be on this file.
class LinksController < ApplicationController
def index
end
def new
end
def create
end
def show
end
def edit
end
def update
end
def destroy
end
end
Awesome
7) Nested Routing
This is freaking awesome!! Let's say you want to nest the routes, for example ;
/links/:link_id/comments
You can do this in routes.rb
file;
resources :links do
resources :comments
end
Pretty cool
8) Talk to the Database
π¦
We can see our database with rails console
command. I know you guys way more clever than me. Haha, I learn a new thing π€. Cheers π».
9) Botstrap stuff
Right now, I know how to use col
in Bootstrap better π₯. I have a hard time understanding the Grid layout before this.
Right now, I feel better using the Grid Layoutπ.
10) Time in Rubyβ°
This is what I mean by time;
Did you see the submitted about 11 hours ago....
below the Link ??
I'm thinking of this at first and configure how to build that stuff. Do a little bit of googling, and walla, Ruby itself have a special command for it!!.
<p>Submitted <%= time_ago_in_words(link.created_at) %> ago by <%= link.user.username %></p>
Haha, super cool !!!
11) Open the link to the new tab
Simple dude, just add target="_blank"
to you a
tag.π
<p>Check out <a href="https://www.freecodecamp.org/" target="_blank" rel="noopener noreferrer">freeCodeCamp</a>.</p>
12) Associations
βοΈ
Associations in Rails is also pretty new to me. I want to create a Comment
that associate with the Link
(same as Hackernews). Associations will help with this.
What I do is that, I add link_id
to comment
table through migration
rails g migration add_user_id_to_comments user_id:integer
Then, I associate them in the model
file ;
class Link < ApplicationRecord
has_many :comments
end
class Comment < ApplicationRecord
belongs_to :link
end
and we have done π₯³.
13) Deploy to Heroku
I use this Gist for setup Heroku stuff.