20210213のGitに関する記事は9件です。

Github ActionsでMerge branchと slack Notify を使ってみた

こんにちはga-です。
今回はじめてgithub Actionsで作ったものを紹介します。

背景

version1,version2,version3と後ろになればなるほど機能が多いプロジェクトがあるとします。
version1はメイン機能,version2は検索機能を追加、version3はそれにさらに履歴機能を追加しているとします。

version1,2,3はそれぞれrelease時期は違いますが現在同時に開発が進んでいます。

version1開発時に重大なバグを発見したとき、後続するversion2,3はそれの影響を受けるので
version1が修正されたらその内容をmergeしたいと思います。

その作業手作業だと面倒ですよね?
じゃあ自動化しましょう。
あとmergeにはconflictはつきものですよね?
じゃあ通知してもらいましょう。

材料

自動マージ用

  • GithubActions
  • Githubのブランチ
    • main(一番最初にリリースされるやつ)
    • develop(一番最初にリリースされるやつの開発ブランチ)
    • develop_v2(二番目にリリースされるやつの開発ブランチ)
    • develop_v3(三番目にリリースされるやつの開発ブランチ)

ミスったら通知もらう用

  • slack
    • アカウント
    • 好きにいじってもいいチャネル
    • webhook
  • GithubActions

作り方(自動マージ編)

それでは早速ですがMerge branchの処理は以下です。
(といってもほぼmerge branchのREADMEですが。。。。)

やりたいことは
main -> develop -> develop_v2 -> develop_v3
と変更をmergeさせていきたいので
例えばdevelop_v2で変更があったときにはdevelop_v3にだけmergeをするように制御をかけておきます。

testGithubActions/.github/workflow/auto_merge.yml
name: Sync multiple branches
on:
  push:
jobs:
  sync-branch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Merge main -> develop
        # ここでpush(pullrequest merge)されたブランチがmainかどうかみる
        if: github.ref == 'refs/heads/main'
        uses: devmasx/merge-branch@v1.3.1
        with:
          type: now
          from_branch: main
          target_branch: develop
          github_token: ${{ github.token }}

      - name: Merge develop -> develop_v2
        # ここでpush(pullrequest merge)されたブランチが`main`または`develop`かどうかみる
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
        uses: devmasx/merge-branch@v1.3.1
        with:
          type: now
          from_branch: develop
          target_branch: develop_v2
          github_token: ${{ github.token }}

      - name: Merge develop_v2 -> develop_v3
        # ここでpush(pullrequest merge)されたブランチが`main`か`develop`または`develop_v2`かどうかみる
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/develop_v2'
        uses: devmasx/merge-branch@v1.3.1
        with:
          type: now
          from_branch: develop_v2
          target_branch: develop_v3
          github_token: ${{ github.token }}

READMEとほぼ同じです。
違いはmergeパターンを3つしているのとpushされたブランチによってmerge先を制御しているぐらいです。

ブランチを用意しておいて、これをmain(master)ブランチにpushするとGithubActionsが動きます。
(後半に書く予定の通知の処理も入っちゃっていますがとりあえずdevelop3にまで変更が反映されていました。)
スクリーンショット 2021-02-13 20.31.49.png

mergeに失敗する

上の実装を行うと確かにmainの変更がdevelop_v3まで反映されますが、
例えばdevelop_v2のreadme.mdを変更してpushしたとしましょう。
その後mainのreadme.mdを変更してpushすると当たり前ですがconflictします。
次はそのconflictが起きたときにslackに通知を送ってもらう方法を実装します。

作り方(通知準備編)

webhookの追加

まずはwebhookをslackに入れましょう
slackのチャンネルの上にあるBrowse Slackの隣にある三点リーダーをクリックして、出てきたメニューの中のAppをクリックします。
スクリーンショット 2021-02-13 19.24.58.png
次にwebhookで検索
スクリーンショット 2021-02-13 19.24.03.png
slackに追加
スクリーンショット 2021-02-13 19.25.12.png
送りたいチャンネルを選択して、Incoming Webhookインテグレーションの追加
スクリーンショット 2021-02-13 19.25.29.png

その後に出てくる画面のインテグレーションの設定のWebhook URLをコピーします。
スクリーンショット 2021-02-13 19.23.24.png

Githubにsecret.SLACK_WEBHOOKの追加

actionを追加したいrepositoryのSettingsNew repository secretをクリック

スクリーンショット 2021-02-13 19.27.27.png
先ほどWebhookでコピーしたURLをオレンジの部分にペースト
スクリーンショット 2021-02-13 19.28.04.png
以下は完了の図
スクリーンショット 2021-02-13 19.28.12.png

作り方(通知を飛ばす)

それでは先ほど作ったauto_merge.ymlをいじっていきます。
- name: Merge main -> develop- name: Merge develop -> develop_v2の間に以下を追加していきます。

testGithubActions/.github/workflow/auto_merge.yml
      - name: Merge main -> develop
      # ~~~省略~~~

      - name: main -> develop try catch
        # この記述は上の処理のstatusがfailureの時のみ動く処理
        if: ${{ failure() }}
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_TITLE: main to v1 merge failed
          SLACK_COLOR: '#3278BD'
          SLACK_USERNAME: Merge Failed
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

      - name: Merge develop -> develop_v2
      # ~~~省略~~~

これだけです。(これもまたreadmeとほぼ変わらない)
これを繰り返すandenvの冗長な記述をまとめた結果が以下になります。

testGithubActions/.github/workflow/auto_merge.yml
name: Sync multiple branches
on:
  push:
jobs:
  sync-branch:
    runs-on: ubuntu-latest
    # まとめたenv
    env:
        SLACK_COLOR: '#3278BD'
        SLACK_USERNAME: Merge Failed
        SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
    steps:
      - uses: actions/checkout@v2

      - name: Merge main -> develop
        if: github.ref == 'refs/heads/main'
        uses: devmasx/merge-branch@v1.3.1
        with:
          type: now
          from_branch: main
          target_branch: develop
          github_token: ${{ github.token }}
      - name: main -> develop try catch
        if: ${{ failure() }}
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_TITLE: main to v1 merge failed

      - name: Merge develop -> develop_v2
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
        uses: devmasx/merge-branch@v1.3.1
        with:
          type: now
          from_branch: develop
          target_branch: develop_v2
          github_token: ${{ github.token }}
      - name: develop -> develop_v2 try catch
        if: ${{ failure() }}
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_TITLE: develop to develop_v2 merge failed

      - name: Merge develop_v2 -> develop_v3
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/develop_v2'
        uses: devmasx/merge-branch@v1.3.1
        with:
          type: now
          from_branch: develop_v2
          target_branch: develop_v3
          github_token: ${{ github.token }}
      - name: develop_v2 -> develop_v3 try catch
        if: ${{ failure() }}
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_TITLE: develop_v2 to develop_v3 merge failed

はい完成!!じゃあ早速さっきのconflictしている状態のmainに対してpushしてみましょう
develop -> develop_v2がconflictでfailureなった結果したのdevelop -> develop_v2 try catchが動いていますね。
スクリーンショット 2021-02-13 19.44.11.png
するとmergeに失敗したdevelop -> develop_v2develop_v2 -> develop_v3の通知がslackに飛んできましたー
スクリーンショット 2021-02-13 19.44.25.png

完成です!
messageなどは任意でいじることできるんで好きにいじってみてもいいかもです。party parrotとかめっちゃ出してアラート感とか出してもいいかもですね。
あとはmentionとかつけることもできるんでアレンジ色々できます。

感想

今回はreleaseタイミングが違うversion違いのアプリをmergeしたいときのGithubActions作ってみました。
GithubActionsっていろんな人がライブラリ作ってmarketplaceにあげてくれているんで簡単に自動化とかできていいですね。
エンジニアっぽいことしたい方は一度readmeだけ作ってガンガンやっちゃってみましょう!
上にも書いたけどparty parrotをメッセージに埋め尽くして目をチカチカさせたい。。。

引用

https://github.com/marketplace/actions/slack-notify
https://github.com/marketplace/actions/merge-branch
https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Gatsby】JS歴ゼロ秒から始める、ポートフォリオサイト構築

0.png

この記事でやること

  • 自分語り
  • Homebrew 導入
  • Xcode 導入
  • Node.js 導入
  • GatsbyCLI 導入

あらすじ

どうも、JS 歴ゼロ秒だった、自称 JC です。
普段はプログラムも含めて、音楽を歌ったり、絵を書いたりと
創作活動を行っている僕です。

普段作っているブツは、
Tumblr や forio などのポートフォリオサービスなどを使って
ログとして残してあるのですが、

ふと Twitter を見ていたらこんなツイートが流れてきました。

いいこと言うじゃん…

まあ僕も作品のジャンルバラバラだったり、
ポートフォリオサイトだと困るなーってところがあったりしていたので、
自分のホームページを作りたいなーと思っていたのでした。
そんな中、ふと Qiita を見ているとこんな記事が話題になっていました。

ボカロ P になったし、爆速ホームページを作る! - Qiita

爆速という魅惑的な単語に惹かれ、少し調べてみると、
僕の思い描いていたカスタマイズが施せることがわかってきました。

よし!オラも Gatsby で爆速ホームページ作っちゃうぞ!!

で き ま し た

できたものがこちらになります。

1.png

実際のページはこちらから

僕は極力シンプルなのが好きなのでこんな感じになりました。
いかがだったでしょうか、それではまたお会いしましょう。
ではでは…で終わるわけあるか!!

というわけで始まります、Gatsby でホームページ作り。

  • プログラミング?if とかならまあわかるけど…
  • JavaScript?そんな名前の言語知らない!!

な僕でも簡単に四苦八苦して
自前のポートフォリオサイトを作ることができたので、
本記事もそういう人向けに記述していきます。

ちなみに僕はシンプルなのが好きなので、
装飾などは特に施さずにやっていきます。

…そもそも Gatsby って何?

  • JavaScript と HTML で構成されたフレームワーク
  • 画像の最適化とビルドによる表示速度の最適化
  • プラグインが豊富で制作のサポートも充実
  • Markdown でブログを作ることができたりする

みたいな感じ。
詳しく知りたい人はググってね。

Gatsby でブログを作るまでの手順

僕の PC が Mac なので Mac での手順を記載します。
Windows とかの人は各自「Gatsby 導入」とかでググってください。

Homebrew からの Gatsby 導入

HomebrewXcodeをインストールする

  1. macOS(または Linux)用パッケージマネージャー — Homebrew
    より、Homebrew というパッケージマネージャーをインストールします。
    これは、要するに「Mac でなんやかんやを自動で管理してくれる便利なやつ」です。
    Homebrew のインストール - Qiita
    を参考にしながら導入していきましょう。

  2. Xcodeを導入します。
    これは、要するに「Mac で開発するときに使うツール」です。
    ないとHomebrewから怒られちゃうので導入しておきましょう。

# 1.
# コマンド省略
$ ~

# 2.
$ xcode-select --install

Node.jsをインストールする

  1. HomebrewNode.jsをインストールします。
    これは、要するに「Java という言語を実行できる環境を構築するやつ」です。
    もっと噛み砕くと「サッカーで言うところのサッカーボール」です。
    これがないとGatsbyを動かせないので導入します。
# 1.
$ brew install node

Gitをインストールする

  1. Gitをインストールします。
    これは、要するに「好きなところでセーブできるセーブポイント」です。
    セーブしなくても俺は突き進むぜ!って人がいたらごめんなさい、
    これがないとGatsbyを世に公開することができません。
    「セーブしたところを世に公開するツール」でもあるのです。
    入れましょう。

  2. Gitを使用するには、名前とメールアドレスが必要です。

    正しいかどうかわかりませんが、僕は名前を Sotono にしています。
    本当は本名入れたほうがいいと思うけど、嫌ならいいと思います…

# 1.
brew install git

# 2.
git config --global user.name "Taro Yamada"
git config --global user.email "taro@gmail.com"

Gatsbyを導入する

  1. おまたせしました、ようやく Gatsby を導入します。
    Gatsby の使用にはGatsby-CLIというものが必要となるので、 これをNode.jsでインストールします。
# 1.
npm install -g gatsby-cli

次回

次回から Gatsby いじりを開始していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【超入門】GitHubリポジトリの作り方

この記事ではGitHubの新しいリポジトリの作り方を初心者に向けて軽く解説します。

前提

GitHubを使い始める前に上記の知識・設定を行っておくと良いです。

Git とは

https://git-scm.com

小規模から大規模開発まで、あらゆるプロジェクトで利用される無料のオープンソース分散バージョン管理システムです。

GitHub とは

https://github.com

Git(ソースコード)をホスティングしてくれるサービスです。
複数人の開発者と協働してコードをレビューしたり、課題管理しながら開発できます。

GitHubの主な機能

ScreenShot 2021-02-13 14.50.20.png

いくつかのタブメニューなどご紹介していきます。

プルリクエスト(Pull Request)

元のブランチから新しくブランチを作り、差分を反映(マージ)したい場合にプルリクエストを作成できます。
プルリクエストでは、変更されたコードに対してレビュー(ディスカッション)が行えます。

レビューする人のことを「レビュアー(reviewer)」
レビューしてもらう人のことを「レビューイ(reviewee)」と呼びます。

レビュアーはプルリクエストに対して3種類のアクションが行えます。

  • Approve(承認する)
  • Request changes(否認する)
  • Comment(承認も否認もしない。質問やディスカッションのコメント)

Approveされたらプルリクエストをマージできます。

イシュー(Issue)

GitHubでは新機能やタスク、バグ等の管理にIssueを使って課題管理できます。
ラベルを用いて、カテゴライズできたり、担当者をアサインできたりとGitHubだけでも優秀な課題機能があります。

#1 などIssueやPullRequestの番号やコミットのハッシュ値を入力して簡単に紐付けできます。
また、プロジェクトボードというカンバン機能もあります。

Issue, PullRequestテンプレート

Issue, Pull Requestのテンプレート機能があります。

  • .github/ISSUE_TEMPLATE.md - Issueを作成するときのテンプレート
  • .github/PULL_REQUEST_TEMPLATE.md - PullRequestを作成するときのテンプレート

と配置するだけです。

ブランチ保護(Protected Branches)

GitHubは直接コミット禁止によるブランチの保護機能が提供されています。
Pull Requestを介して、レビューや自動テストによるチェックが通過しないとマージできないといった制約を付けてブランチを保護できます。

GitHub Actions(ワークフロー)

GitHub ActionsとはGitHubが提供するCI/CD(継続的インテグレーション/継続的デリバリー)サービスです。

  • .github/workflows/*.yml ワークフローはYAMLで定義します。

私のリポジトリではこんな感じで使ってるので雰囲気だけ知ってもらえればと思います。

GitHub Actionsについては公開リポジトリであれば無料で利用できます。
非公開リポジトリは無料枠+従量課金となります。

無料プランでも2000分/月利用できるので小規模な開発であれば問題ないでしょう。
プロジェクトによってCI/CDする内容が大きく変わるので深くは説明しません...(できません)

fork(フォーク)

forkとは、他の人のリポジトリを自分のリポジトリへコピーすることです。
リポジトリをフォークすることにより、オリジナルのリポジトリに影響を与えることなく自由に変更できます。
また、変更した内容をオリジナルのリポジトリへプルリクエスト(提案)して貢献できます。

Wiki(ウィキ)

WikiはWikiです。
プロジェクトに関するドキュメントなどをまとめるところです。

GitHubリポジトリの作り方

本題です。

新規リポジトリの作成

https://github.com/new

Repository template: テンプレートリポジトリを選択できます。
Owner: リポジトリ所有者を選択できます。
Repository name: リポジトリの名称です。優れたリポジトリ名は短く覚えやすいものです。良い名前を付けましょう。GitHubがランダムなリポジトリ名を考えてくれます(笑)
Description: リポジトリの概要です(任意)
Public/Private: リポジトリの公開/非公開設定です。この設定をミスるとこうなります
Initialize this repository with: 予めGitHubがテンプレファイルを用意してくれます。(任意)

ちなみにリポジトリの名前はあとからでも変更できます。

Gitのセットアップ

リポジトリの新規作成ページでREADMEやLICENCEの選択などを行った場合は不要です。

こんな感じにGitHubにファイルがpushされていればセットアップ完了です。

設定ファイル

コラボレータの追加

コラボレータ(Collaborator)とはリポジトリのコアな開発者です。
リポジトリに対して、pushやmergeといった権限が与えられます。

非公開リポジトリの場合はコラボレータに追加されないとリポジトリの参照も行えません。

また、公開リポジトリではあればコントリビューター(Contributor)として外部から貢献できます。
直接pushやmergeはできないので、リポジトリをforkしてPull Requestを送るといった手順を踏む必要があります。

Settings > Manage access > Invite a collaborator

招待メールが送られるので、相手が招待リンクを承認したらコラボレータへ追加されます。

リポジトリオプション設定

Settings > Options > Settings

リポジトリ名の変更が行えます。
テンプレートリポジトリの設定ができます。
SNS等でリポジトリのリンクを共有した際の画像を設定できます。
(未設定の場合はリポジトリオーナーのアイコン画像になります)

Settings > Options > Features

GitHubの機能の有効化/無効化が行えます。
IssueやWikiなど外部のツールを使う場合は無効化しておくと良いでしょう。

  • Wikis
  • Restrict editing to collaborators only
  • Issues
  • Sponsorships
  • Projects
  • Preserve this repository
  • Discussions

Settings > Options > Merge button

プルリクエストをマージする場合、マージコミット、スカッシュ、リベースの任意の組み合わせでマージできます。

いずれか一つのボタンのみを有効化させておくと混乱しないので良いです。
(プロジェクト内で相談して決めてください)

  • Allow merge commits (デフォルト)
    • マージコミットが作成されます。
  • Allow squash merging
    • そのプルリクエストのコミットは1つのコミットにsquashされます。
  • Allow rebase merging
    • トピックブランチのすべてのコミットが、マージコミットなしに個別にベースブランチに追加されます。

個人的には Allow squash merging が好きです。

自動マージを許可する設定です。
必要なレビューとステータスチェックに合格するとプルリクエストを自動的にマージする設定です。
有効化しておくと良いです。

プルリクエストがマージされた後、リモートリポジトリのブランチが自動的に削除されます。
マージ済みのブランチを残しておく必要はないので有効化しておきましょう。
(削除したブランチもあとから復元できます)

Settings > Branches > Branch protection rules

ブランチの保護ルールの設定をします。
保護ルールをどのくらい強めに設定するかはプロジェクト内で相談して決めてください。

Branch name parttern: ブランチ名を指定します。(パターンマッチも利用可能)

Require pull request reviews before merging: マージする前にプルリクエストのレビューを要求します。
必要な数の承認レビューがないとマージできなくなります。
Dismiss stale pull request approvals when new commits are pushed: 新しいコミットが追加されるとレビュー承認は却下されます。
Require review from Code Owners: オーナーの承認が必ず必要になります。

これ全部チェックすると相当マージするハードルが高くなります。
開発速度にも影響出るので、最低レビュー1個必要と設定すればとりあえず良いでしょう。
必要に応じてレベルをあげてください。

Require status checks to pass before merging: マージする前にステータスチェックに合格する必要があります。
CIが通ってないのにマージされるとブランチを保護する意味がなくなるので、必ず有効化しましょう。

Require branches to be up to date before merging: マージする前にブランチを最新にする必要があります。
この設定を行うことで最新のコードでテストされていることが保証されます。必ず有効化しましょう。
開発速度の速いリポジトリだと他のPRがマージされる度にマージが必要になるので、ケースバイケースかもです。

Require signed commits: 署名付きコミットが必要

署名済みコミットを必須にする設定
署名がないとマージすることができなくなります。(いるかな?)

Require linear history: 線形履歴が必要

マージボタンの設定で Allow merge commits 以外のAllow squash mergingAllow rebase mergingを採用する場合は有効化しましょう。

Include administrators: 管理者を含める

管理者もこのブランチ保護の制限の対象に含めるか
チェックを入れると管理者も同様にマージできなくなります。
通常は有効化して、緊急時のみ無効化する感じがいいかも?

Allow force pushes: 強制プッシュを許可する。(絶対に有効化しないでください)
Allow deletions: ブランチ削除を許可する。(絶対に有効化しないでください)

管理者を含むすべての人に適用されるルールです。
これを設定してしまうとブランチを保護する意味がなくなるので必ず無効化しましょう。

Settings > Secrets > Actions secrets

シークレットキーの設定です。
アクセスキーやシークレットキー、APIキー等、コミットに含めたくないものを登録します。
GitHub Actions等でデプロイする際にシークレットで登録したキーを参照する時に使います。

さいごに

GitHubのリポジトリを作成する際の最低限の内容をまとめました。
より詳しく知りたい方は公式ドキュメントを参照してください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Windows版】GitBash初期設定その2

SSH鍵を作成する

git-command
$ ssh-keygen  ← このコマンドを打つ
Generating public/private rsa key pair.
Enter file in which to save the key (/c/XXXX/XXXX/.ssh/id_rsa):
Created directory '/c/XXXX/XXXX/.ssh'.
Enter passphrase (empty for no passphrase):  ← ここでパスワードを入力する
Enter same passphrase again: ← もう一度、パスワードを入力する
Your identification has been saved in /c/XXXX/XXXX/.ssh/id_rsa
Your public key has been saved in /c/XXXX/XXXX/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:jigR+e9jDsTZXe4tCTub5qhEoJyC3fupme93LDZSPnM etoum@DESKTOP-5GT8N6M
The key's randomart image is:
+---[RSA 3072]----+
|                 |
|   .             |
|  +       .      |
|oo.* o . o       |
|+oo B . S .      |
|.  + + o.+ o     |
|  . = oo+.+ .    |
|   o *+oX+E.     |
|    =BOB+B       |
+----[SHA256]-----+

SSH鍵を設定する(BitBuketの場合)

  • Labelに任意の名前を入力する
  • KeyにSSH鍵の内容をコピペする image.png

SSH鍵の内容の確認方法

git-command
$ cat ~/.ssh/id_rsa.pub ← このコマンドを打つ(要は作成したSSH鍵の中身を確認する)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDXGPmiWlFhJQibfV0dsvPrmQgSRXDyF6ruNsQb6Rvk6UWBRpfjR9RqdJOij/2jIXYCa9VNGakPjUoaSx5ZBxc7pSOkklacbMrct9epbImLPVe4khtKPEv2/81wzmQnk0OymwI36vI5wIxBMSTABTuJyprRLn3+0hLWM1T48DJms4YPoXWujqGjUIkN6sUd5pzwRvq6AO1VBelYS7nHUaondcQvqJDlvXmz8tTeCNxqgh1AaUls8+T//aZD1QKFshZ/aKxiAZakLnkjUelTPBIl4QF/lR61JfcdwuvKq8BOtOOljjxXNeK1tUoNz1wAs7b2iaEvENOwPBrbyB4dSn6tHaXUDyaYRALxReX7cp6WZ66OmnTpM7quqW1+mId1PIQu8XGOXuV7O5R3e2ggrabcr58orFRBS84LOsROCABPcQ2gSWUIfsm+Y1Tnd5gA4Lty7K/YuFg2+m2nKsuCmLaLXIVL7g3DYdhi6+qOE+aPiONwaWOs3IPguaULETnN4EE= etoum@DESKTOP-5GT8N6M


試しにCloneしてみる

git-command
$ git clone リモートリポジトリアドレス ← このコマンドを打つ
Cloning into 'XXXX'...
The authenticity of host 'bitbucket.org (2406:da00:ff00::34cc:ea4a)' can't be established.
RSA key fingerprint is SHA256:zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes ← 「yes」と打つ
Warning: Permanently added 'bitbucket.org,2406:da00:ff00::34cc:ea4a' (RSA) to the list of known hosts.
Enter passphrase for key '/c/XXXX/XXXX/.ssh/id_rsa': ← パスワードを入力する
remote: Counting objects: 68, done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 68 (delta 18), reused 0 (delta 0)
Receiving objects: 100% (68/68), 7.24 KiB | 353.00 KiB/s, done.
Resolving deltas: 100% (18/18), done.

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Windows版】GitBash初期設定その1

コミットするときに使用するユーザ名とメールアドレスを設定する

  • コミットの編集者情報が正しく保管されるようにする
git-command
$ git config --global user.name "ここにユーザ名を書く"
$ git config --global user.email ここにメールアドレスを書く
  • 日本語の文字化け防止
git-command
$ git config --global core.quotepath false

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Windows版】GitBashインストール手順

GitBash.exeをDownloadする

Downloadサイト(https://gitforwindows.org/)
今回は「Git-2.30.1-64-bit.exe」を使用します。
image.png

DownloadしたGitBash.exeを起動する

image.png

「NEXT」ボタンを連打する

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

この画面は「checkout as-is, commit as-is」を選択する

image.png

また「NEXT」ボタンを連打する。そして「Install」ボタンを押下してInstallを開始する

image.png
image.png
image.png
image.png
image.png
image.png

この画面が表示されたら終わり

image.png

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

間違えて消してしまったブランチをgit reflogで復活させる

間違えて必要なブランチを消してしまった....
又は間違えてresetする箇所を間違えた...
というときに使えるコマンド

何が起こったか

commitだけして、pushしたと完全に思い込んで、マスターブランチにマージされたからいらないやと思ってブランチを消してしまった

git branch -dで消せば良かったのにそのときは雑にgit branch -Dで消してしまったのでマスターにpushしてない部分があることに気が付かなかった...orz)

一瞬焦ったけど、そんなときこそgit reflog

ブランチを復活させる

$ git reflog
f5f6828 (HEAD -> dev, origin/dev, origin/HEAD) HEAD@{0}: pull origin dev: Fast-forward
c3983b8 HEAD@{1}: ...
b94cda4 HEAD@{2}: ...

復活させたいHEADを見つけたら

$ git branch <ブランチ名> HEAD@{2}

復活できた〜〜良かった。

感想

ブランチ消す前にちゃんとdiffで差分確認するとかしないとだめですね。笑
一瞬ヒヤッとしたけどコミットは忘れずにしてたおかげでちゃんと戻せました。良かった〜〜。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6.1ハンズオン(1)~掲示板基本機能実装

ターゲット

  • Rails、Rubyを全く知らない人
  • 何らかのプログラミング言語でコードを書いたことがある人
  • ある程度shellの操作に慣れている人
  • macがなくてwindowsしかない人

目的

Rails6.1で基本的な機能を雑に触れながらそれっぽいアプリを作る

やること

  • Gitの設定
  • ログインなしで書き込めるネット掲示板を作る
  • ベースはこれを使う + vscodeに拡張機能を入れて開発

1. 開発環境を整える

1-1. vscodeを整える

vscodeをインストールする。

Visual Studio Code - コード エディター | Microsoft Azure

これでWSLに接続して開発できる(これ以降の拡張機能は必要に応じてWSL上にインストールされる。)

Remote - WSL - Visual Studio Marketplace

日本語化

Japanese Language Pack for Visual Studio Code - Visual Studio Marketplace

アイコンをわかりやすく表示

Material Icon Theme - Visual Studio Marketplace

Ruby関連

Ruby - Visual Studio Marketplace

補完とかしてくれる言語サーバ solargraphさん

# solargraphをインストール
gem install solargraph

Ruby Solargraph - Visual Studio Marketplace

endを自動で入れてくれる

endwise - Visual Studio Marketplace

draw.ioを使いたい

Draw.io Integration - Visual Studio Marketplace

1-2. Gitを整える

first commit

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

github SSH認証の準備

参考にさせていただくもの:
WSL2 から起動した VSCode DevContainer に SSH agent で Git の鍵を渡す - Qiita

cd ~
ssh-keygen -t ed25519 -P ""
# 何も入れずにEnter
cd .ssh
more id_ed25519.pub
# 内容をコピー

Build software better, together

SSH and GPG keysで「New SSH Key」ボタンを押す。
わかりやすいTitle(WSL2とか)を入力、Keyにコピーした公開鍵を貼り付け、Add

~/.bashrcを開いて以下のコードを追加

if [ -z "$SSH_AUTH_SOCK" ]; then
   # Check for a currently running instance of the agent
   RUNNING_AGENT="`ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[:space:]'`"
   if [ "$RUNNING_AGENT" = "0" ]; then
        # Launch a new instance of the agent
        ssh-agent -s &> $HOME/.ssh/ssh-agent
   fi
   eval `cat $HOME/.ssh/ssh-agent`
fi

ssh-add $HOME/.ssh/id_ed25519

github上にリポジトリを新規作成、(ここでは「Rails6.1_hands_on」という名前)

git remote add origin git@github.com:hirorocky/Rails6.1_hands_on.git
git push -u origin master
# Rails6.1だとまだ”master”

2. 掲示板を作る

2-0. Railsの基礎知識:MVCモデル

詳しくは「Rails MVC」で検索!
私は正しく理解している自信はないですが、こんな図を描いてみました↓

Untitled.png
リクエストが来たら、Rails上のroutes.rbがコントローラーとアクション(=メソッド)を決めて、コントローラー上のアクションでモデルからデータを取りながら、ビューを作って、その結果をブラウザに返すイメージです。

2-1. 設計

◆モデル図

(拡張機能により、〇〇.drawioというファイルを作ればvscode上でdraw.ioが使える!)
Untitled 1.png

◆ワイヤーフレーム(?詳しくない)

Untitled 2.png

4枚のページが必要そう。

  • communities_controller#index:トップページ
  • communities_controller#new→#create:コミュニティ作成ページ
  • communities_controller#show:1つのコミュニティ&コメント一覧
  • comments_controller#new→#create:コメント投稿ページ

なぜこのコントローラー×アクションの組み合わせなのかは聞かないでください。

2-2. 実装

2-2-1. モデル

DB上に各テーブルを作る。

' rails generate model <モデル名> <カラム名>:<型>...'

でモデルに関するファイルを自動で作ってくれる。

rails generateはrails gと省略できる。※以降gで書きます。

rails g model Community title:string owner_name:string
rails g model Comment author_name:string content:text community:references

db/migrateフォルダ内に、2つのファイル(マイグレーションファイル)ができる。

以下のコマンドでDBにテーブルを作成する。

# sqlite上にRails用DBを作成
rails db:setup
# DB上にマイグレーションファイルをもとにテーブルを作成
rails db:migrate

app/models/community.rbにて

class Community < ApplicationRecord
  has_many :comments
end

app/models/comment.rbにて

class Comment < ApplicationRecord
  belongs_to :community
end

こうするだけで、RailsのORMがいい感じにしてくれる。

※ちょっと試すにはターミナルでrails console(rails cでも可)コマンド。

irb(main):001:0> commu = Community.create(title: 'コミュニティタイトルです', owner_name: 'たろう')
   (0.4ms)  SELECT sqlite_version(*)
  TRANSACTION (0.1ms)  begin transaction
  Community Create (0.5ms)  INSERT INTO "communities" ("title", "owner_name", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "コミュニティタイトルです"], ["owner_name", "たろう"], ["created_at", "2021-02-13 02:21:28.386695"], ["updated_at", "2021-02-13 02:21:28.386695"]]
  TRANSACTION (5.0ms)  commit transaction
=> #<Community id: 1, title: "コミュニティタイトルです", owner_name: "たろう", created_at: "2021-02-13 02:21:28.386695000 +0000", updated_at: "2021-02-13 02:21:28.386695000 +0000">

irb(main):002:0> commu.title
=> "コミュニティタイトルです"

irb(main):003:0> commu.comments.create(author_name: 'じろう', content: "コメント\nああああ")
  TRANSACTION (0.1ms)  begin transaction
  Comment Create (0.5ms)  INSERT INTO "comments" ("author_name", "content", "community_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["author_name", "じろう"], ["content", "コメント\nああああ"], ["community_id", 1], ["created_at", "2021-02-13 02:26:21.103087"], ["updated_at", "2021-02-13 02:26:21.103087"]]
  TRANSACTION (5.1ms)  commit transaction
=> #<Comment id: 1, author_name: "じろう", content: "コメント\nああああ", community_id: 1, created_at: "2021-02-13 02:26:21.103087000 +0000", updated_at: "2021-02-13 02:26:21.103087000 +0000">

irb(main):004:0> commu.comments.create(author_name: 'じろう', content: "コメント2\nああああ")
  TRANSACTION (0.1ms)  begin transaction
  Comment Create (0.5ms)  INSERT INTO "comments" ("author_name", "content", "community_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["author_name", "じろう"], ["content", "コメント2\nああああ"], ["community_id", 1], ["created_at", "2021-02-13 02:26:35.918169"], ["updated_at", "2021-02-13 02:26:35.918169"]]
  TRANSACTION (7.1ms)  commit transaction
=> #<Comment id: 2, author_name: "じろう", content: "コメント2\nああああ", community_id: 1, created_at: "2021-02-13 02:26:35.918169000 +0000", updated_at: "2021-02-13 02:26:35.918169000 +0000">

irb(main):005:0> commu.comments
  Comment Load (0.2ms)  SELECT "comments".* FROM "comments" WHERE "comments"."community_id" = ? /* loading for inspect */ LIMIT ?  [["community_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Comment id: 1, author_name: "じろう", content: "コメント\nああああ", community_id: 1, created_at: "2021-02-13 02:26:21.103087000 +0000", updated_at: "2021-02-13 02:26:21.103087000 +0000">, #<Comment id: 2, author_name: "じろう", content: "コメント2\nああああ", community_id: 1, created_at: "2021-02-13 02:26:35.918169000 +0000", updated_at: "2021-02-13 02:26:35.918169000 +0000">]>

ログを見ると、rubyのコードをSQLに変換して、DBを操作しているのがなんとなくわかると思います。

ここでは見ませんが、上記コードだけで、DBに1つのcommunityレコードと2つのcommentレコードができています。

2-2-2. Communityのコントローラー・ビュー

◆コントローラー

rails g controller communities index new create show

設計段階で必要なコントローラーとビューがわかったので、

上記コマンドを入力。すると色々作成される(いらないものもできてしまう...※この辺は設定でいい感じにできますがここでは触れません)

app/controllers/communities_controller.rbのアクションの中にコードを入れる

class CommunitiesController < ApplicationController
  def index
    @communities = Community.all
  end

  def new
    @community = Community.new
  end

  def create
    @community = Community.new(community_params)
    if @community.save
      redirect_to communities_path
    else
      render :new
    end
  end

  def show
    @community = Community.find(params[:id])
    @comments = @community.comments
  end

  private

  def community_params
    params.require(:community).permit(:title, :owner_name)
  end
end

@hogeはインスタンス変数で、この文脈で必要な知識としては、

「インスタンス変数はビューに渡せる」ということです。

community_paramsメソッドはStrong Parameterというやつです。セキュリティ的に必要なもので、詳しくはググってください。

◆ルーティング

Rails.application.routes.draw do
  root to: 'communities#index'
  resources :communities, only: %i[index new create show]
end

自動生成されたものは全部削除、ルートをcommunities_controllerのindexアクションに割りあて、resourcesメソッドでcommunities_controller関連のルーティングを一気に作成。

rails routes

で設定されているルーティングを見ることができ、またもっと見やすくしたいときは、

ブラウザ上で「http://[::1]:3000/rails/info/routes」で見れる。

◆ビュー

ビュー関連はapp/viewsの中に入っている。

自動で作成されたcreate.html.erbはいらないので削除。

早くhamlを使いたい。

一旦、見た目ガン無視の最低限の機能を実装する。

app/views/communities/index.html.erb

<h1>掲示板</h1>

<%= link_to 'コミュニティ作成', new_community_path %>

<% @communities.each do |community| %>
  <div>
    <p><%= link_to community.title, community_path(community) %></p>
    <p><%= community.created_at %></p>
    <p><%= community.owner_name %></p>
  </div>
<% end %>

<% %>の中にrubyのコードを入れることができる。

<%= %>はrubyの評価結果をそのままhtmlに書き出す。

=かそうじゃないかは慣れだと思う。

app/views/communities/new.html.erb

<h1>コミュニティ作成</h1>

<%= form_with model: @community do |form| %>
  <%= form.label :title %>
  <%= form.text_field :title %>
  <%= form.label :owner_name %>
  <%= form.text_field :owner_name %>

  <%= form.submit '作成' %>
<% end %>

※form_withは一時期デフォルトがremote: trueだったが、local: trueになった。

app/views/communities/show.html.erb

<h1><%= @community.title %></h1>

<% @comments.each do |comment| %>
  <div>
    <p><%= comment.author_name %></p>
    <p><%= simple_format(comment.content) %></p>
    <p><%= comment.created_at %></p>
  </div>
<% end %>

2-2-3. Commentのコントローラー・ビュー

◆コントローラー

rails g controller comments new create

app/controllers/comments_controller.rb

class CommentsController < ApplicationController
  before_action :set_community

  def new
    @comment = @community.comments.new
  end

  def create
    @comment = @community.comments.new(comment_params)
    if @comment.save
      redirect_to community_path(@community)
    else
      render :new
    end
  end

  private

  def set_community
    @community = Community.find(params[:community_id])
  end

  def comment_params
    params.require(:comment).permit(:author_name, :content)
  end
end

◆ルーティング

Rails.application.routes.draw do
  root to: 'communities#index'
  resources :communities, only: %i[index new create show] do
    resources :comments, only: %i[new create]
  end
end

rails routesコマンドでこうなる。

Prefix                Verb URI Pattern                                       Controller#Action
                 root GET  /                                                 communities#index
   community_comments POST /communities/:community_id/comments(.:format)     comments#create
new_community_comment GET  /communities/:community_id/comments/new(.:format) comments#new
          communities GET  /communities(.:format)                            communities#index
                      POST /communities(.:format)                            communities#create
        new_community GET  /communities/new(.:format)                        communities#new
            community GET  /communities/:id(.:format)                        communities#show

◆ビュー

app/views/communities/show.html.erb

<%= link_to '←戻る', communities_path %>
<h1><%= @community.title %></h1>

<%= link_to 'コメントする', new_community_comment_path(@community) %>

<% @comments.each do |comment| %>
  <div>
    <p><%= comment.author_name %></p>
    <p><%= simple_format(comment.content) %></p>
    <p><%= comment.created_at %></p>
  </div>
<% end %>

app/views/comments/new.html.erb

<%= link_to '←戻る', community_path(@community) %>
<h1>コメントする</h1>

<%= form_with model: [@community, @comment] do |form| %>
  <%= form.label :author_name %>
  <%= form.text_field :author_name %>

  <%= form.label :content %>
  <%= form.text_area :content %>

  <%= form.submit '投稿' %>
<% end %>

app/views/comments/create.html.erbは削除。

2-2-4. Gemfileの変更

左上に出ている表示が邪魔なので、rack-mini-profilerを削除。

デバッグ用にpry-railsを入れる。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.0'

gem 'rails', '~> 6.1.2', '>= 6.1.2.1'
gem 'sqlite3', '~> 1.4'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'
# gem 'redis', '~> 4.0'
# gem 'bcrypt', '~> 3.1.7'
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-rails'
end

group :development do
  gem 'web-console', '>= 4.1.0'
  # gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  gem 'spring'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

ひとまず完成。

次回:Rails6.1ハンズオン(2)~見た目をそれっぽくする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6.1開発ハンズオン(1)

ターゲット

  • Rails、Rubyを全く知らない人
  • 何らかのプログラミング言語でコードを書いたことがある人
  • ある程度shellの操作に慣れている人
  • macがなくてwindowsしかない人

目的

Rails6.1で基本的な機能を雑に触れながらそれっぽいアプリを作る

やること

  • Gitの設定
  • ログインなしで書き込めるネット掲示板を作る
  • ベースはこれを使う + vscodeに拡張機能を入れて開発

1. 開発環境を整える

1-1. vscodeを整える

vscodeをインストールする。

Visual Studio Code - コード エディター | Microsoft Azure

これでWSLに接続して開発できる(これ以降の拡張機能は必要に応じてWSL上にインストールされる。)

Remote - WSL - Visual Studio Marketplace

日本語化

Japanese Language Pack for Visual Studio Code - Visual Studio Marketplace

アイコンをわかりやすく表示

Material Icon Theme - Visual Studio Marketplace

Ruby関連

Ruby - Visual Studio Marketplace

補完とかしてくれる言語サーバ solargraphさん

# solargraphをインストール
gem install solargraph

Ruby Solargraph - Visual Studio Marketplace

endを自動で入れてくれる

endwise - Visual Studio Marketplace

draw.ioを使いたい

Draw.io Integration - Visual Studio Marketplace

1-2. Gitを整える

first commit

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

github SSH認証の準備

参考にさせていただくもの:
WSL2 から起動した VSCode DevContainer に SSH agent で Git の鍵を渡す - Qiita

cd ~
ssh-keygen -t ed25519 -P ""
# 何も入れずにEnter
cd .ssh
more id_ed25519.pub
# 内容をコピー

Build software better, together

SSH and GPG keysで「New SSH Key」ボタンを押す。
わかりやすいTitle(WSL2とか)を入力、Keyにコピーした公開鍵を貼り付け、Add

~/.bashrcを開いて以下のコードを追加

if [ -z "$SSH_AUTH_SOCK" ]; then
   # Check for a currently running instance of the agent
   RUNNING_AGENT="`ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[:space:]'`"
   if [ "$RUNNING_AGENT" = "0" ]; then
        # Launch a new instance of the agent
        ssh-agent -s &> $HOME/.ssh/ssh-agent
   fi
   eval `cat $HOME/.ssh/ssh-agent`
fi

ssh-add $HOME/.ssh/id_ed25519

github上にリポジトリを新規作成、(ここでは「Rails6.1_hands_on」という名前)

git remote add origin git@github.com:hirorocky/Rails6.1_hands_on.git
git push -u origin master
# Rails6.1だとまだ”master”

2. 掲示板を作る

2-0. Railsの基礎知識:MVCモデル

詳しくは「Rails MVC」で検索!
私は正しく理解している自信はないですが、こんな図を描いてみました↓

Untitled.png
リクエストが来たら、Rails上のroutes.rbがコントローラーとアクション(=メソッド)を決めて、コントローラー上のアクションでモデルからデータを取りながら、ビューを作って、その結果をブラウザに返すイメージです。

2-1. 設計

◆モデル図

(拡張機能により、〇〇.drawioというファイルを作ればvscode上でdraw.ioが使える!)
Untitled 1.png

◆ワイヤーフレーム(?詳しくない)

Untitled 2.png

4枚のページが必要そう。

  • communities_controller#index:トップページ
  • communities_controller#new→#create:コミュニティ作成ページ
  • communities_controller#show:1つのコミュニティ&コメント一覧
  • comments_controller#new→#create:コメント投稿ページ

なぜこのコントローラー×アクションの組み合わせなのかは聞かないでください。

2-2. 実装

2-2-1. モデル

DB上に各テーブルを作る。

' rails generate model <モデル名> <カラム名>:<型>...'

でモデルに関するファイルを自動で作ってくれる。

rails generateはrails gと省略できる。※以降gで書きます。

rails g model Community title:string owner_name:string
rails g model Comment author_name:string content:text community:references

db/migrateフォルダ内に、2つのファイル(マイグレーションファイル)ができる。

以下のコマンドでDBにテーブルを作成する。

# sqlite上にRails用DBを作成
rails db:setup
# DB上にマイグレーションファイルをもとにテーブルを作成
rails db:migrate

app/models/community.rbにて

class Community < ApplicationRecord
  has_many :comments
end

app/models/comment.rbにて

class Comment < ApplicationRecord
  belongs_to :community
end

こうするだけで、RailsのORMがいい感じにしてくれる。

※ちょっと試すにはターミナルでrails console(rails cでも可)コマンド。

irb(main):001:0> commu = Community.create(title: 'コミュニティタイトルです', owner_name: 'たろう')
   (0.4ms)  SELECT sqlite_version(*)
  TRANSACTION (0.1ms)  begin transaction
  Community Create (0.5ms)  INSERT INTO "communities" ("title", "owner_name", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "コミュニティタイトルです"], ["owner_name", "たろう"], ["created_at", "2021-02-13 02:21:28.386695"], ["updated_at", "2021-02-13 02:21:28.386695"]]
  TRANSACTION (5.0ms)  commit transaction
=> #<Community id: 1, title: "コミュニティタイトルです", owner_name: "たろう", created_at: "2021-02-13 02:21:28.386695000 +0000", updated_at: "2021-02-13 02:21:28.386695000 +0000">

irb(main):002:0> commu.title
=> "コミュニティタイトルです"

irb(main):003:0> commu.comments.create(author_name: 'じろう', content: "コメント\nああああ")
  TRANSACTION (0.1ms)  begin transaction
  Comment Create (0.5ms)  INSERT INTO "comments" ("author_name", "content", "community_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["author_name", "じろう"], ["content", "コメント\nああああ"], ["community_id", 1], ["created_at", "2021-02-13 02:26:21.103087"], ["updated_at", "2021-02-13 02:26:21.103087"]]
  TRANSACTION (5.1ms)  commit transaction
=> #<Comment id: 1, author_name: "じろう", content: "コメント\nああああ", community_id: 1, created_at: "2021-02-13 02:26:21.103087000 +0000", updated_at: "2021-02-13 02:26:21.103087000 +0000">

irb(main):004:0> commu.comments.create(author_name: 'じろう', content: "コメント2\nああああ")
  TRANSACTION (0.1ms)  begin transaction
  Comment Create (0.5ms)  INSERT INTO "comments" ("author_name", "content", "community_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["author_name", "じろう"], ["content", "コメント2\nああああ"], ["community_id", 1], ["created_at", "2021-02-13 02:26:35.918169"], ["updated_at", "2021-02-13 02:26:35.918169"]]
  TRANSACTION (7.1ms)  commit transaction
=> #<Comment id: 2, author_name: "じろう", content: "コメント2\nああああ", community_id: 1, created_at: "2021-02-13 02:26:35.918169000 +0000", updated_at: "2021-02-13 02:26:35.918169000 +0000">

irb(main):005:0> commu.comments
  Comment Load (0.2ms)  SELECT "comments".* FROM "comments" WHERE "comments"."community_id" = ? /* loading for inspect */ LIMIT ?  [["community_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Comment id: 1, author_name: "じろう", content: "コメント\nああああ", community_id: 1, created_at: "2021-02-13 02:26:21.103087000 +0000", updated_at: "2021-02-13 02:26:21.103087000 +0000">, #<Comment id: 2, author_name: "じろう", content: "コメント2\nああああ", community_id: 1, created_at: "2021-02-13 02:26:35.918169000 +0000", updated_at: "2021-02-13 02:26:35.918169000 +0000">]>

ログを見ると、rubyのコードをSQLに変換して、DBを操作しているのがなんとなくわかると思います。

ここでは見ませんが、上記コードだけで、DBに1つのcommunityレコードと2つのcommentレコードができています。

2-2-2. Communityのコントローラー・ビュー

◆コントローラー

rails g controller communities index new create show

設計段階で必要なコントローラーとビューがわかったので、

上記コマンドを入力。すると色々作成される(いらないものもできてしまう...※この辺は設定でいい感じにできますがここでは触れません)

app/controllers/communities_controller.rbのアクションの中にコードを入れる

class CommunitiesController < ApplicationController
  def index
    @communities = Community.all
  end

  def new
    @community = Community.new
  end

  def create
    @community = Community.new(community_params)
    if @community.save
      redirect_to communities_path
    else
      render :new
    end
  end

  def show
    @community = Community.find(params[:id])
    @comments = @community.comments
  end

  private

  def community_params
    params.require(:community).permit(:title, :owner_name)
  end
end

@hogeはインスタンス変数で、この文脈で必要な知識としては、

「インスタンス変数はビューに渡せる」ということです。

community_paramsメソッドはStrong Parameterというやつです。セキュリティ的に必要なもので、詳しくはググってください。

◆ルーティング

Rails.application.routes.draw do
  root to: 'communities#index'
  resources :communities, only: %i[index new create show]
end

自動生成されたものは全部削除、ルートをcommunities_controllerのindexアクションに割りあて、resourcesメソッドでcommunities_controller関連のルーティングを一気に作成。

rails routes

で設定されているルーティングを見ることができ、またもっと見やすくしたいときは、

ブラウザ上で「http://[::1]:3000/rails/info/routes」で見れる。

◆ビュー

ビュー関連はapp/viewsの中に入っている。

自動で作成されたcreate.html.erbはいらないので削除。

早くhamlを使いたい。

一旦、見た目ガン無視の最低限の機能を実装する。

app/views/communities/index.html.erb

<h1>掲示板</h1>

<%= link_to 'コミュニティ作成', new_community_path %>

<% @communities.each do |community| %>
  <div>
    <p><%= link_to community.title, community_path(community) %></p>
    <p><%= community.created_at %></p>
    <p><%= community.owner_name %></p>
  </div>
<% end %>

<% %>の中にrubyのコードを入れることができる。

<%= %>はrubyの評価結果をそのままhtmlに書き出す。

=かそうじゃないかは慣れだと思う。

app/views/communities/new.html.erb

<h1>コミュニティ作成</h1>

<%= form_with model: @community do |form| %>
  <%= form.label :title %>
  <%= form.text_field :title %>
  <%= form.label :owner_name %>
  <%= form.text_field :owner_name %>

  <%= form.submit '作成' %>
<% end %>

※form_withは一時期デフォルトがremote: trueだったが、local: trueになった。

app/views/communities/show.html.erb

<h1><%= @community.title %></h1>

<% @comments.each do |comment| %>
  <div>
    <p><%= comment.author_name %></p>
    <p><%= simple_format(comment.content) %></p>
    <p><%= comment.created_at %></p>
  </div>
<% end %>

2-2-3. Commentのコントローラー・ビュー

◆コントローラー

rails g controller comments new create

app/controllers/comments_controller.rb

class CommentsController < ApplicationController
  before_action :set_community

  def new
    @comment = @community.comments.new
  end

  def create
    @comment = @community.comments.new(comment_params)
    if @comment.save
      redirect_to community_path(@community)
    else
      render :new
    end
  end

  private

  def set_community
    @community = Community.find(params[:community_id])
  end

  def comment_params
    params.require(:comment).permit(:author_name, :content)
  end
end

◆ルーティング

Rails.application.routes.draw do
  root to: 'communities#index'
  resources :communities, only: %i[index new create show] do
    resources :comments, only: %i[new create]
  end
end

rails routesコマンドでこうなる。

Prefix                Verb URI Pattern                                       Controller#Action
                 root GET  /                                                 communities#index
   community_comments POST /communities/:community_id/comments(.:format)     comments#create
new_community_comment GET  /communities/:community_id/comments/new(.:format) comments#new
          communities GET  /communities(.:format)                            communities#index
                      POST /communities(.:format)                            communities#create
        new_community GET  /communities/new(.:format)                        communities#new
            community GET  /communities/:id(.:format)                        communities#show

◆ビュー

app/views/communities/show.html.erb

<%= link_to '←戻る', communities_path %>
<h1><%= @community.title %></h1>

<%= link_to 'コメントする', new_community_comment_path(@community) %>

<% @comments.each do |comment| %>
  <div>
    <p><%= comment.author_name %></p>
    <p><%= simple_format(comment.content) %></p>
    <p><%= comment.created_at %></p>
  </div>
<% end %>

app/views/comments/new.html.erb

<%= link_to '←戻る', community_path(@community) %>
<h1>コメントする</h1>

<%= form_with model: [@community, @comment] do |form| %>
  <%= form.label :author_name %>
  <%= form.text_field :author_name %>

  <%= form.label :content %>
  <%= form.text_area :content %>

  <%= form.submit '投稿' %>
<% end %>

app/views/comments/create.html.erbは削除。

2-2-4. Gemfileの変更

左上に出ている表示が邪魔なので、rack-mini-profilerを削除。

デバッグ用にpry-railsを入れる。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.0'

gem 'rails', '~> 6.1.2', '>= 6.1.2.1'
gem 'sqlite3', '~> 1.4'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'
# gem 'redis', '~> 4.0'
# gem 'bcrypt', '~> 3.1.7'
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-rails'
end

group :development do
  gem 'web-console', '>= 4.1.0'
  # gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  gem 'spring'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

ひとまず完成。

次回(?)見た目をそれっぽく整えるの巻。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む