I have released my first self-made web app!
Tags: portfolio, beginners, rails, java
Published: 2021-11-14 05:39:50

## 1. Introduction

[![main image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1g441kf52vcmjtimwsx.jpg)](https://www.5keeps.com/en)

Hi! I'm Daichi from Japan who started learning programming to be a web developer on November 2020. After 1 year, I finally could release my first web app "5Keeps" which is a simple bookmark app.

【Link to 5Keeps】
https://www.5keeps.com/en

【Source Code on GitHub】
https://github.com/daichihayasaka/five_keeps_ver01/blob/master/README.md

The first half of this post describes this app, and the second half summarizes the learning process over the course of a year.

## 2. About 5Keeps
### 2-1. Summary
#### Issues to be solved
This service can provide solutions to users who are facing the following issues with their browser's bookmarking function.
- Difficult to access to the information quickly because of the too many bookmarks .
- It's hard to organize too many bookmarks.

#### Solution
I have solved the problem by limiting the functions as follows. Save the information needed right now in plain sight.
- Up to 5 groups can be created.
- Up to 5 links can be created for each group.
- Links must have a title.

#### How to use
Please refer to the top page of the application.
https://www.5keeps.com/en

### 2-2. Functions/ Features
#### User-related　　　
- create, view, update, delete
- authentication/authorization
- remember me function
- account activation by email
- password reset by email
- guest-login function (details is written later)

#### Group-related　　　
- create, view, update, delete by asynchronous communication

#### Link-related　　　
- create, view, update, delete by asynchronous communication
- display data of an open graph protocol. (fetch from URL by Nokogiri gem)
- search function

#### Others　　　
- contact function（using Gmail）
- switch language function（Japanese/ English）

### 2-3. Details of guest-login function
When a visitor click on the 「Free Trial」 button, a temporary guest account is created, so that they can use this application just for a trial. Later on visitor can sign up for a permanent account if they like it. I implement this guest-login function as below.

**1. Add a boolean guest attribute to the users table**
（db/migrate/xxxx_add_guest_to_users.rb）

```ruby
class AddGuestToUsers < ActiveRecord::Migration[6.1]
  def change
    add_column :users, :guest, :boolean, default: false
  end
end
```

**2. Add route for guest page**
（config/routes.rb）
```ruby
post '/guest', to:'users#create_guest'
get '/guest',  to:'static_pages#guest'
```

**3. Add create_guest action to users controller**
（app/controllers/users_controller.rb）
```ruby
  # POST /guest
  # Current user is guest => Redirect to guest page
  # Current user is nil => Create new guest account
  def create_guest
    if current_user && current_user.guest?
      redirect_to guest_path
    else
      user = User.create(name: "Guest User",
                        email: SecureRandom.alphanumeric(15) + "@guest.com",
                     password: SecureRandom.alphanumeric(10),
                        guest: 1)
      log_in user
      flash[:success] = t('.flash.success')
      redirect_to guest_path
    end
  end
```

**4. Add guest action to static_pages controller**
（app/controllers/static_pages_controller.rb）
```ruby
  # GET /guest
  # Current user is nil or Current user is not a guest account => Redirect to root url
  def guest    
    redirect_to root_url if !current_user || !current_user.guest?
  end
```

**5. Delete guest user regularly**
Guest accounts deleted automatically by Heroku scheduler.
Run below rake task automatically at 4:00 PM UTC everyday.
（lib/tasks/scheduler.rake）

```ruby
desc "This task is called by the Heroku scheduler add-on"
task :delete_all_guests => :environment do
  puts "Updating guests..."
  # Destroy all the guest accounts that were created over a day ago.
  User.where(guest: :true).where("created_at < ?", 1.day.ago).destroy_all
  puts "done."
end
```

### 2-4. ER diagram
![ER diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gur2m26gnp28suo0l0bf.png)

### 2-5. Technologies used 
- Ruby 2.6.3
- Ruby on Rails 6.1.4
- Vanilla JS
- Sass
- MySQL 8.0
- Heroku
- Minitest

### 2-6. Plan to improve
#### Usability
- Make asynchronous communication faster
- Improve UI and UX on mobile screen.
- Implement social login function.
- Implement SNS sharing function.

#### Technologies
- Rewrite test by RSpec.
- Using AWS instead of Heroku.
- Remake app as REST API with React.

## 3. The road to release 5Keeps
### 3-1. Start learning (Nov 2020-Jan 2021)
I started learning by using Japanese web service which the users can learn programming. What I learned for the first 3 month is HTML, CSS, JavaScript, SQL, Git, Linux, Ruby, Ruby on Rails. 
I still remember struggling to understand JavaScript's `forEach()`, and being excited when I use UNIX commands on the terminal for the first time, which is reminiscent of a programmer I had imagined.

### 3-2. Struggling with "Rails Tutorial" (Feb-May 2021)
After learning the basic skills, I started learning practical web development skills with Ruby on Rails using "Rails Tutorial".

However I've had a hard time since the first chapter because I couldn't deploy to Heroku no matter how I tried. It took some time, but I managed to solve the problem by pursuing the cause without giving up. Looking back on it now, I think it was a good experience.

After that, I repeated following process again and again.
①Leave the tutorial because it was too difficult
②Learn a specific topic separately
③Come back to the tutorial
I gradually made progress, and by the time I entered a vocational training school in June, I had completed 10 chapters.

### 3-3. Deepen my understanding of Object-oriented programming (Jun-Aug 2021)
I felt that I had reached my limit in continuing to study web development while continuing my previous job. So I decided to take advantage of the public vocational training school program provided by the government. It allows people to learn specialized skills while receiving unemployment benefits. I left the company on May 2021, and started to go to the school which I can learn "web development by Java" on June 2021.

At school, the lessons went in the following order: Java → HTML/CSS → JavaScript → Servlet/JSP → SQL → Linux → Git.
Since I had not learned Java before, I concentrated on Java for a time, even after school and on weekends.

Java is different from Ruby in that it specifies many things explicitly. For example, when to create a method, you explicitly specify whether there is a return value, whether there are arguments, and the type of each.
Thanks to the many times I created classes, interfaces, and methods using Java in the school, I gained a physical understanding of arguments, return value, instance variable, constructor, accessor, inheritance, etc., and a deeper understanding of object-oriented programming.

After I had settled down to learn Java to some extent, I resumed the Rails Tutorial and completed all 14 chapters.　Finally, I started implementing the first self-made application in my life　which is "5Keeps".

### 3-4. Deepen my understanding of CRUD and Database (Sep 2021)
The school is now in the production period for the first presentation at the end of September. Classes are held only in the mornings and afternoons are for production. During this period, the development of "5Keeps" was carried out in two ways. Servlet/JSP at school and Rails after school and on weekends.

Servlet is a basic program for web development in Java. Servlet by itself is responsible for the Controller in the MVC model, and works with JSP (like ERB in Ruby) in charge of the View to dynamically generate web pages.

Servlet/JSP is not a framework, so compared to Rails, which is a Ruby framework, or Spring Boot, which is a Java framework, there are many things I have to do manually. It is a lot of work, but I learned a lot from it, and the following two points in particular have been very useful for my later development.

#### *The flow of CRUD processing becomes ingrained in my body*
In Servlet, the method to be called changes depending on the type of request. GET request call `doGet()`, and POST request call `doPost()`. In the course of Servlet/JSP development, I repeated the process of using different methods for different types of requests many times. Thanks to this, the flow of CRUD processing has become ingrained in my body. A typical example is as follows
- `doGet()`: Get the value from the URL parameter / Get the value from the database → Display by JSP
- `doPost()`: Get the value entered in the form → Update the database → Redirect to `doGet()`

#### *Strong awareness of the database*
In the first round of Rails Tutorial, I used the OR mapper "Active Record" and didn't pay much attention to the database. In the development by Servlet, I had to connect to the database manually, write a lot of SQL, and check it with "MySQL Workbench" every time I added data. Thanks to this, I became very aware of the database even when developing applications using Rails.

### 3-5. Implement with googling (Oct 2021)
After the successful presentation of the Servlet/ JSP version of "5Keeps", the last major topic of the school was learning the Java framework "Spring Boot".　By learning it in comparison to Rails, I gained a better understanding of the framework, O/R mapper, package management, etc.

On the other hand, the Rails version of "5Keeps" has completed the implementation of the base functions such as user authentication, and has entered into the implementation of group and link related functions. From this point on, I'm in uncharted territory beyond the Rails Tutorial.
I was worried at first, but I implemented the functions one by one, while looking up articles in Japanese and sometimes in English. I learned to solve problems on my own by implementing with googling.

#### *Difficulties [Asynchronous Communication]*
The create, view, update, and delete of groups and links are all done through asynchronous communication to improve the UX, but I had a hard time integrating Rails and JavaScript, such as adding events to newly added elements.

#### *What I'm particular about [Obtaining OGP information]*
Since the app's functions are simple, it was difficult to make the design attractive. To solve this, I used Ruby's Nokogiri gem to obtain the OGP information of the linked website from the URL. Web scraping was an unknown technology, but after referring to several articles, I was very excited when I was able to get the OGP image for the first time.

### 3-6. Finally released! (Nov 2021)
Until just before the release, I had to solve some problems specific to iOS (e.g., buttons changing color and shape), and also added a "How to use" section to the top page after a school teacher pointed out that it was difficult to understand what the app was for. On November 5th, I finally released 5Keeps!

## 4. Conclusion
I started with no experience and learned programming for a year, but to be honest, I underestimated it at first. Programming is difficult.　Just when I think I have overcome one wall, another huge wall appears. However, as I continued to learn, I was able to do more and more things little by little, and I began to enjoy it more and more.　

I have released 5Keeps, but it is not finished yet.　I will continue to improve the app and make it better and better. There are still many things I want to learn, so I would like to succeed in finding a job as a web developer, gain more experience, and continue to improve my skills.