【個人開発】『草刈山雄』GitHubで生やした草を日本の山の標高と比較するアプリを開発しました！

# はじめに
はじめまして！ [@muramyy1](https://twitter.com/muramyy1)と申します！
メーカーの営業職から未経験でエンジニア転職を目指しております。
プログラミング学習中の身であるため、技術的な内容に誤りを含んでいる可能性があります。
おかしな記述がありましたらコメント等で教えていただけたらと思います:pray:

# サービス名： [草刈山雄](https://www.kusakari-yamao.com/)
## 開発の背景
エンジニアになりたい、技術力を向上させたいと日々学習していく中でどうしてもモチベーションが保てないときがあると思います。 今までの学習のなかでコードを書いて生やした草を現実にあるものと比較することで更なる学習意欲を掻き立てることができるのではないかと考えて開発に着手しました。

## サービス概要
プログラミング学習者が学習のモチベーションを維持するために、 GitHubで生やした草を刈り取って、積み上げた高さを日本に山の標高と比較する 学習モチベートサービスです。特にサービス名は機能と関係ありません:seedling:

## サービスの使い方
GitHubアカウント名を入力するだけでcontribution数を取得することができ自分の学習の積み上げが可視化できます。
その他GitHubログインすることでこれまでの草刈履歴を残すことができます。

# 工夫した点・苦労した点
### 1.ログインなしでもサービスを使用できる
本サービスはGitHub認証を行い、ログインできるサービスになっています。
認証のハードルが高い人もいるのでログインなしでも一部機能を使えるようにしています。

### 2.山の標高別に表示されるマーカーを変更する
[![Image from Gyazo](https://i.gyazo.com/bf61303d766d7d778eaf7a2813b30fd5.png)](https://gyazo.com/bf61303d766d7d778eaf7a2813b30fd5)

上の画像のように地図に表示される山の標高でマーカーを分けています。
それを実現させたのが以下のコードになります。
なにも難しいことはありません。条件分岐してるだけですw


```javascript
// マーカーの設定
      const markerOption = {
        position: markerLatLng,　 // 緯度経度の値
        map,
        icon: function(){
                if (mountains[i]['elevation'] >= 3000) {
                  return {
                    url: "<%= asset_path '画像' %>",
                  }; 
                } else if (mountains[i]['elevation'] >= 2500) {
                  return {
                    url: "<%= asset_path '画像' %>",
                  };
                } else if (mountains[i]['elevation'] >= 2000) {
                  return {
                    url: "<%= asset_path '画像' %>",
                  };
                } else if (mountains[i]['elevation'] >= 1000) {
                  return {
                    url: "<%= asset_path '画像' %>",
                  };
                } else {
                  return {
                    url: "<%= asset_path '画像' %>",
                  };
                }
              }(),
      };
```



### 3.gem graphql-client
GraphQLってなに？からスタートしましたがなんとか実装することができました。
今回はgraphql-clientを使ってGitHubのcontributionの数を取得していますが、[octkit](https://github.com/octokit/octokit.rb)でもできるようです。調査不足・・・

実装は以下のページをご覧ください。
https://github.com/github/graphql-client

graphal-clientを導入する

```Gemfile
gem "graphql-client"
```

GraghQLのクエリ、gemの設定等をモジュールにまとめました。

```ruby:models/concerns/graphql_api.rb
module GraphqlApi
  extend ActiveSupport::Concern

  included do
    AUTH_HEADER = "Bearer #{ENV['GITHUB_ACCESS_TOKEN']}"

    HTTPAdapter = GraphQL::Client::HTTP.new("URLを入力する") do
      def headers(context)
        { "Authorization": AUTH_HEADER }
      end
    end
    Schema = GraphQL::Client.load_schema(HTTPAdapter)
    Client = GraphQL::Client.new(schema: Schema, execute: HTTPAdapter)

    TotalContributionsQuery = Client.parse <<-'GRAPHQL'
      query($user: String!) {
        user(login: $user) {
          contributionsCollection {
            contributionCalendar {
              totalContributions
            }
          }
        }
      }
    GRAPHQL
  end

  private

  def self.graphql_result(query, variables = {})
    Client.query(query, variables:).data
  end
end
```

取得したデータを取り出します。
`user:なんちゃら`で書くことでクエリを動的に変更することができます。こちらについても公式のドキュメントを読むのがいいと思います。
キャメルケースではなくスネークケースで書きましょう。

```models/contribution.rb
api_result = GraphqlApi.graphql_result(GraphqlApi::TotalContributionsQuery, user: account_name).user.contributions_collection.contribution_calendar.total_contributions
```


# 主な使用技術
### バックエンド
- Ruby3.1.2
- Ruby on Rails 7.0.4

### フロントエンド
- HTML/SCSS/Javascript
- CSSフレームワーク
  - Tailwind css
  - daisyUI

### 主要ライブラリ
- OmniAuth
- MetaTags(SEO)
- graphql-client
- RSpec(テスト)
- RuboCop(リントチェック)
- Gon
- kaminari

### インフラ
- Heroku
- PostgreSQL(データベース)

### その他
- GitHub GraphQL API
- GoogleMapsAPI

### 技術選定について 
できるだけ最短で公開するために、メインで学習しているRuby on Railsで作成しました。フロントに関しても見た目に関しても時間をかけたくないという理由からdaisyUIを導入しています。流行りのtailwind cssではありますが便利なテンプレートが多くあったり、レスポンシブ対応も簡単に実装ができるのでストレスなく開発に取り組めました。

# 開発期間

- MVPリリースまで約１ヶ月
- 本リリースまで1ヶ月

# おわりに
 改善すべきところしかないサービスですが、０からサービスを作成してみて個人サービスを開発することの楽しさを味わうことができました。また、このように技術記事を書くなかでもっとこうしたらよかったなーとか、どんどん湧いて出てくるのでそれは今後のサービス改善に活かしていきたいと思います。

 ここまで拙い記事を読んでいただきありがとうございます！ツッコミたいところが多かったと思いますが、それはコメントにお願いしますw
Let's 草刈！:fist::sparkles: