Amirul Asyraf

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;

Screenshot 2020-12-05 at 10.10.23.png

The Link Page Screenshot 2020-12-05 at 10.12.01.png

Page when user Sign in ; Screenshot 2020-12-05 at 10.13.36.png

Submit link page ;

Screenshot 2020-12-05 at 10.14.32.png

Account page ;

Screenshot 2020-12-05 at 10.15.19.png


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 ;

Screenshot 2020-12-05 at 08.10.09.png

note: Every time you do a migration, your schema.rb file will change based on your previous migration or after you do rails db:mirate command

2) Devise

I love how Devise gems ease my life for implementing authentication πŸ”₯.

It handles my user acc management

Screenshot 2020-12-05 at 08.15.55.png

Sign in/up stuff

Screenshot 2020-12-05 at 08.16.27.png

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.

Screenshot 2020-12-05 at 09.52.10.png

Right now, I feel better using the Grid LayoutπŸš€.

10) Time in Ruby⏰

This is what I mean by time;

Screenshot 2020-12-05 at 09.55.14.png

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.


Follow me on Twitter || RSS

#hackernews #heroku #rails #stuff I made