Clickyz Overview

Christian Cain
5 min readJun 22, 2020

At Flatiron School we were tasked with building a project to highlight our understanding of Sinatra.

For my project I decided to create a 3D mechanical keyboard editor.

This was the product of a deep rabbit hole into JavaScript, copious amounts of coffee, and a lot of free time on my hand thanks to COVID-19.

The Requirements

For each project at Flatiron, we are tasked with displaying core concepts that we learn in each section. We’re given a number of deliverables that our application must meet in order to “pass”.

Sinatra Project Requirements:

  1. Build an MVC Sinatra application
  2. Use ActiveRecord & multiple Models
  3. At least one Has-Many relationship
  4. Have User accounts & handle Authentication
  5. Data Validations
  6. Ensure that users can edit and delete only their own resources

The Inspiration

I am greatly interested in hand made things, and having essential/minimal possessions.

I stumbled upon a few videos of people building mechanical keyboards from scratch, and quickly understood why the hobby has grown such an occult following.

After many YouTube videos, I began window shopping for various parts. Though I never could imagine how the pieces would look together.

AHA! A pain point :)

The Front-End

I decided to start with the front-end because the core of the app centered around the ability to make edits to a keyboard. The data modeling, authentication, and MVC flow all revolved around this.

I initially began with displaying a 2D SVG file.

This worked for a starter, but I had something more realistic in mind!

A LOT of time on my hands

The pandemic that we faced in 2020 definitely shook things up for a lot of people. No one ever saw it coming!

I found myself being furloughed from 2 part-time jobs. I decided to make the most of the unfortunate circumstances, and dedicated many hours to coding during this time.

I decided I would do my best to turn a negative into a positive!

Going 3D

I fiddled around with 3D auto-cad software, and began working on an actual 3D keyboard.

I found these schematics online of a manufactured keyboard case, and started from there.

With the help of YouTube & coffee, I quickly learned the minimum about this free software called Rhino3D. After a few hours this is what I had.

Allowing Users to Edit

I began researching online for ways to interact with 3D objects, and found this library called p5.js that allowed you to import .obj files and edit them as WEBGL objects.

The library is a lightweight library that renders 3D objects onto a canvas, and handles effects like lighting & textures.

I broke the keyboard into 3 separate components: primary keys, alt keys, and case.

I then created a form with inputs that changed the color of the objects in the p5 canvas.

On to the Back-End

Now that I had an MVP of sorts, I could then go on to framing out my entire application.

I always like to begin each project with the Modeling. I needed classes for Builds and Users. Users and Builds would have a One-to-Many relationship.

I set these Models up, created the associated migrations, and added validations to ensure that bad data couldn’t be persisted.

This was my schema.

create_table “builds”, force: :cascade do |t| 
t.string “name”
t.string “case”
t.integer “user_id”
t.string “primary_color”
t.string “alt_color”
t.string “img_url”
end
create_table “users”, force: :cascade do |t|
t.string “email”
t.string “password_digest”
t.string “username”
end

I jumped into to the console, and verified that everything was working :)

Setting up the Controller & Views

I then started on the Controllers and associated Routes. The app would only have a few pages.

I began by creating a Builds controller. This would handle the Creating, Reading, Updating, and Deleting of Builds.

The bulk of these Actions were standard CRUD functionality that we had learned throughout the curriculum.

The trickiest part was handling the images of the builds.

Saving images to Google Cloud Storage

Once the User made their edits in the Browser, I then converted the canvas into Base64, then sent that data back to the server.

I then used this Base64 data to create & save a png file.

In development, I was saving these files locally. But with ambitions of deploying to Heroku, I learned that Heroku chooses to purge their data quite frequently and recommended saving images to a 3P storage.

Now I had another technology to learn about!

I once again consulted with YouTube and got a decent understanding of Google Storage.

I created a developer account. Configured a Bucket. Installed the ‘google-cloud-storage’ gem into my app. Then after much tweaking, I was able to save the data to their cloud, and associate the generated URL to my Build instances.

Authentication & Authorization

During this section, we learned about the importance of proper security measures including Authentication.

We learned about the ‘bcrypt’ gem, encryption & password salting, and the importance of restricting User privileges.

I went on to create a Users controller to handle authentication & session creation.

I then crafted security measures to restrict Users to only be able to edit/view their personal Builds.

I then had everything configured that I wanted to, and was happy with the final project.

https://github.com/SenseiCain/clickyz

Conclusion

This project is one that I’m most proud of. Not because of the complexity, but because I was able to start with an idea of my own, then bring it into fruition.

This project showed me the freedom of software!

My one regret was spending so much time on the Front-End aspect, as apposed to highlighting the features of Sinatra. Then again, that’s kind of what makes Sinatra so great. It’s ability to spin up lightweight applications quickly.

Overall, it was a great learning experience :)

--

--