The process behind creating a ruby gem
Tags: ruby, rails
Published: 2021-03-16 09:39:57

Lately, especially in the rails community, we've been witnessing lots of new stuff like the [hotwire](https://github.com/hotwired), and the new encryption system.
{% twitter 1369790017724375048 %}

If you notice carefully, all of these have been extracted from pre-existing applications.

So you might be wondering, what's the deal with extractions? Why can't I just start writing the gem?

The most obvious answer that I can give you is that it is difficult to visualize the usage of the gem itself. For example, say you're building an authorization library gem. You would probably need some `method` that would run before the `controller` actions and pass in some `attributes` like the `current_user`, `role`, `action` name, etc to the `policy`. Also, should the policies be scoped to the `model`? But if you do that, how would you deal with policies that do not have a `model`?

In order to answer all of these questions, it would be much easier to first implement the functionality into your existing rails application and then extract it if you wish to do so.

## The story behind
Recently, I was working on a project that had the traditional dashboard design; plenty of `SVG` icons, user avatar, unnecessary graphs, and charts, etc. The Figma wireframes used icons from [heroicons](https://heroicons.com/), and naturally, the first thought that came to my mind was to look for a gem that provided a `views` helper method for rendering out the icons. 

I found a couple of gems that did this, and I quickly installed one of them and started using it. After some time, I realized the gem that I installed wasn't extensible. I wasn't able to pass other `HTML` attributes other than the ones supported by the gem. So the only thought that came into my mind was to create a helper method that would take in any `HTML` attribute like the `styles`, `class`, `aria`, `data`, etc.

The first thing that I did was to look for other `ruby` gems that did something like this. I came across [octicons](https://github.com/primer/octicons/tree/master/lib/octicons_gem) by GitHub and liked how they implemented the gem.

### Step 1 - Figuring out the syntax of the helper method
```eruby
<%= heroicon "user", class: "custom-class", aria: { label: "user icon" } %>
``` 
The first argument is the icon name, and the rest of the options are `HTML` attributes. Rails already provides a neat helper method called the `content_tag`, so it was a no-brainer for me to utilize it.

### Step 2 - Setting up the defaults
Each icon library has some defaults, like `stroke-width`, `viewBox`, etc. In the case of [heroicon](https://heroicons.com/), they had two variants, namely: outline and solid. So I came up with the following syntax:
```eruby
<%= heroicon "user", variant: "solid" %>
```
or, just
```eruby
<%= heroicon "user" %>
```
for rendering the `outline` version of the icon.

### Step 3 - Implementing the logic
After you come with a syntax that you like, the next step would be to test out the helper method and write the logic for it. You're pretty much done now.

### Step 4 - Bundling into a gem
What's on this step? Initialize the gem repo, copy and paste all the logic and the tests, write your gem's description, and publish it to the world.

## Self-promotion
This is the gem ([rails_heroicon](https://github.com/abeidahmed/rails-heroicon)) that I implemented following this process. Be sure to stargaze it and use it in your next project if you feel the need to use `SVG` icons.
> I was so satisfied with this process that I created another gem for [feathericons](https://feathericons.com/). The gem is called [rails_feather](https://github.com/abeidahmed/rails_feather).

## Conclusion
I agree that there isn't one way of doing the right thing. Especially in software engineering, it's all about trial and error. I found this process quite productive and useful and thought I would share it with you all.
I hope you find it useful.