OmniAICreator/Qiita-1.07M huggingface dataset:
[MySQL / MySQLWorkbench] パーティション分割済みの巨大テーブルをRenameしたら、レコード件数が0件になった

# 概要

タイトルの通り。
ただし、後でわかったのだが、この件数減少は表面上の一時的な現象だった模様。

# 結論

待てばよし。

# 発生状況詳細

数億レコード規模のテーブルを扱っていたのだけれど、訳あってテーブル名変更することになった。

状況は以下の通り。

- MySQLWorkbenchを使っていた
- テーブル名変更前は、レコードが数億件レベルで存在することを確認済み
- そのテーブルはpartition分割されていた
- Renameを実施したところ、レコード行数 (`Table rows:`)が一時的に`0件`と表示された
    - これは、MySQLWorkbenchの `TableInspector` 機能による `Info` タブ画面上の表示件数


ちなみに、テーブル名変更のために実行したSQLは以下の通り。

```sql
RENAME TABLE <スキーマ名>.<テーブル名> TO <新テーブル名>;

/* Example */
RENAME TABLE staging_database.old_user TO user;
```

# 経過

- 最初はめちゃ慌てた
- 慌ててすぐに逆 Rename して、旧テーブル名に戻した (新テーブル名 --> 旧テーブル名)
- すると、レコードの件数は元の状態へとすぐに復活した
- しかし、落ち着いて再度 Rename を実行 (旧テーブル名 --> 新テーブル名)
- 際 Rename 後、 30分程度 待ったところ、8000万件近くまでレコード件数が回復(？)していた。
- さらにしばらく待つと、元のテーブルの件数にほぼ近い値に復旧 (ただし、なぜか完全には一致せず...)


# 補足

なお、partition側の `TABLE_NAME` については、 親のテーブル名変更のタイミングで、自動的に新しいテーブル名に書き換わっていた。
なので、partition側の `TABLE_NAME` を一つ一つ書き換えるとか、そういう面倒なことはしなくても大丈夫。

partitionの状況は以下のSQLで確認可能。

```sql
SELECT
  TABLE_SCHEMA, TABLE_NAME, PARTITION_NAM,
  PARTITION_ORDINAL_POSITION, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
/* WHERE文は、必要なければ削除して実行してもOK */
WHERE TABLE_NAME = 'テーブル名' AND TABLE_SCHEMA = 'スキーマ名';
```

# 参考資料

partitionの情報確認をするためのSQLは、以下の記事に書かれていました。

https://oreno-it3.info/archives/712

# 感じたこと

こういう情報がどこにもなかったので、半日〜1日近くこの問題の対処をしてしまった。
ので、記事化した。

みんな、困った後解決したら、記事を書こう。
UBuntu 22.04 をWSL2 環境で動かすメモ

下記手順で実行する。

# WSL2の有効化
・Ｗin＋Ｒ → control でコントロールパネルを開く
・プログラム　→　Windowsの機能の有効化または無効化から、下記３つを有効化。OKボタン押下後、再起動。
　１，Linux用Windowsサブシステム
　２，Windowsハイパーバイザープラットフォーム
　３，仮想マシン プラットフォーム
・Windows Terminal をMicrosoft Store から入手し、Windows terminal上で `wsl --set-default-version 2` を実行
・コマンド実行結果にある https://aka.ms/wsl2kernel を任意のブラウザで開く
・`最新のWSL 2 Linuxカーネル更新プログラムパッケージ` リンクをクリックしてダウンロードし、インストールを実行
・Windows terminal上で `wsl --set-default-version 2` を実行し、先ほどと表示されるメッセージが変わっていることを確認

# Ubuntuインストール
・Microsoft Store にて"Ubuntu"で検索し、任意のディストリビューションを選択して「入手」を実行
※ここで"Ubuntu" を選択して入手したところ、後々エラーが発生したので Ubuntu 22.04 を推奨（2023/09/29時点）
以降はWindows Terminal より操作すればよい。

# トラブル発生時：Ubuntuアンインストール方法
・Microsoft Store にて、Ubuntu 22.04 ではなく Ubuntuをインストール→再起動後、Ubuntuの画面にて`Instaling, this may take a few minutes...` と表示される。この文の次に下記エラーが表示された。
`WslResisterDistribution failed with error: 0x80370110`
・Ubuntuのアンインストールを実行しようとしたが、Windowsの設定→アプリと機能 にて Ubuntu が見つからなかったので、別の方法を試した。
・Windows Terminal にて `wslconfig /l` にて、現在WSLに登録されているディストリビューションを調べて、そのバージョンをアンインストールする。確か `wslconfig /u Ubuntu` と実行した気がする（うろ覚え）
・アンインストールが正常に終了したら、Ubuntu 22.04 をMicrosoft Store から「入手」する

# Windows Terminal とWSL2の起動方法
Windowsキー押下→wtを入力→Windows Terminalを実行

# Ubuntuの再起動方法
Windows再起動後にUbuntu22.04の起動方法がわあらなかったので調べた。
Windows Terminalを起動して `wsl` コマンドを実行してみたら、インストールしたときと明らかに違うUbuntuが起動して焦った。だって`ls` コマンドの実行結果が前回と違ったんだもの。
![誰だお前？！.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222234/f272043e-b9fe-d06d-8cb2-34abae195ffe.png)

Windows Terminal を右クリックして、インストールしたUbuntuを選択したら、ちゃんと前回のが開いた。よかったよかった。
![Linux再起動方法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222234/4461f953-3573-399d-e46b-ab645935b1a2.png)



# 参考
[Windows 10でWSL 2を有効化する方法](https://news.mynavi.jp/techplus/article/liunx_win-54/)
[Windows Subsystem for Linux（WSL）をインターネット接続のないオフライン環境にインストールする → 「指定されたパスが見つかりません」と出たら wslconfig.exe /l してから /u でアンインストールして解決](https://min117.hatenablog.com/entry/2020/04/06/232908)
Azure OpenAI ServiceをRESTで使う

# はじめに

Azure OpenAI ServiceのChat機能をRESTで利用するために確認すべき項目をまとめる。

# 前提条件

- Azure OpenAI Serviceのアクセス申請が承認されていること
- Azure OpenAIのリソースが作成されていること

# AzureのWebコンソールで確認すべきポイント

## Azure Portal | Overview

StatusがAcitveであることを確認します。また、Locationによって、サポートされているModelに違いがある場合があるため、あわせて確認して下さい。

![AzureOpenAI_Overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1557529/12cc816a-8f77-127f-8632-f1cec9cbc1b8.png)

## Azure Portal | Keys and Endpoint

API KeyとLanguage APIのURLエンドポイントを確認します。

![AzureOpenAI_Keys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1557529/a9a1de45-eb30-ca05-7fd9-5bc48659c9a4.png)

## Azure Portal | Networking

ネットワークの設定はアクセス可否の設定と直結しており重要なポイントとなります。Selected Networks and Private Endpointsを指定する場合は、[Azure AI サービスの仮想ネットワークを構成する](https://learn.microsoft.com/ja-jp/azure/ai-services/cognitive-services-virtual-networks?tabs=portal)もご参照の上、アクセス可能なネットワークをご確認下さい。

- All networks: インターネットを含む全てのネットワークからのアクセスを許可
- Selected Networks and Private Endpoints: 指定するネットワークからのアクセスのみを許可
- Disabled: アクセスを無効化

![AzureOpenAI_Networking.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1557529/4020e510-3d9d-3de1-f97b-0745cce92b3e.png)

## Azure Portal | Model deployments

Model deploymentsは、Azure Web Consoleから`Azure OpenAI Studio`に移動する必要があるようです。

![AzureOpenAI_ModelDeployments.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1557529/329439aa-4454-c4a5-470c-722ac3680ebd.png)

## Azure OpenAI Studio | Deployments

上記ページから移動した先は下記ページになります。Deploymentsは、URLエンドポイントに含む必要があるため、確認しておく必要があります。

![AzureOpenAIStudio_Deployments.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1557529/f467f4a1-4146-f1bc-67b2-e5562a1c5c97.png)

## Azure OpenAI Studio | Models

こちらは、利用可能なModelを確認するページとなります。今はGPT-4を利用申請を行なっていない状態です。モデルの詳細は[Azure OpenAI Serviceモデル](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/models)をご参照下さい。

![AzureOpenAIStudio_Models.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1557529/0bc3b751-e0c9-32f1-b1d3-270a54f3939a.png)

# サンプルスクリプト

AzureのドキュメントページやAzure OpenAI Stduioでは様々なサンプルコードが見つかりますが、動く場合と動かない場合があるため、動作が確認できたcurlコマンドを案内します。macOSのTerminalでは、`zsh no matches found:`エラーが出力されます。下記はURLをダブルクオートで囲っているのでMacosでもLinuxでもコマンドが通ることを確認しています。

`URLエンドポイント`、`設定したdeployment名`、`指定のKEY`は上記の各ページにてご確認の上、入れ替えてご利用下さい。

```curl
curl "https://{URLエンドポイント}/openai/deployments/{設定したdeployment名}/chat/completions?api-version=2023-05-15" \
  -H "Content-Type: application/json" \
  -H "api-key: {指定のKEY}" \
  -d '{"messages":[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Does Azure OpenAI support customer managed keys?"},{"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."},{"role": "user", "content": "Do other Azure AI services support this too?"}]}'
```


# 参考

- [クイックスタート: Azure OpenAI Service で GPT-35-Turbo と GPT-4 を使い始める](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/chatgpt-quickstart?tabs=command-line&pivots=rest-api)
vscodeの中でブラウザを開く方法

## vscode⇔ブラウザを行ったり来たりするのがめんどくさい！

今まで私がフロントエンドの開発を行うときは、
1. vscodeでコーディング・ターミナルでプロジェクト実行
2. chromeでローカルホストにアクセスして画面確認

の流れで作業していました。

会社の作業環境はディスプレイが2台あるため、特に不便は感じていなかったのですが、自宅にはディスプレイが1台しかなく、vscodeとchromeを行ったり来たりしなければなりませんでした。

最近これが億劫になってきたので、「vscode内でブラウザも開けないかなぁ」と調べていたところ、「Browse Lite」という拡張機能を見つけたので、ご紹介します。

## 「Browse Lite」の使い方
「Browse Lite」はvscodeのタブ内でブラウザを表示することができる機能です。
拡張機能のメニューを開いて、「Browse」と検索すると上位に表示されるので、これをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124676/25e08fb7-0fdc-0116-9864-fe53f7de8f1c.png)

インストールが完了したら、Ctrl＋Shift＋Pでコマンドパレットを開き、「Browse Lite: Open...」と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124676/bc6fc339-2252-9fd8-43ab-cae4b0c09f58.png)

Enterを押してコマンドを実行すると、「Browse Lite」のタブが開き、検索ができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124676/6f4fccfb-1eaa-d645-a349-1bfc349675ad.png)

「about:blank」と入力されているところにbingのURLを貼り付けてEnterを押すと、ちゃんとbingの画面に遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124676/83e64e5b-2aa1-cd95-42d4-935e1a5c50da.png)

「Browse Lite」を使用すると、下記画像のように、
コーディング・プロジェクト実行・動作確認（※）をvscode内でできます！
※正式な動作確認を行う際は、chromeやedgeなどのブラウザアプリを使用したほうが良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124676/425d2552-611b-0c1d-8c50-ed07a845d012.png)

## まとめ
「Browse Lite」をインストールすると、フロントエンド開発をほぼvscode内でできそうです。
本当はbingの検索画面を初期表示のデフォルトに設定したかったのですが、設定方法がよくわからず、断念しました。
（拡張機能の設定に「Start Url」というものがあり、いろいろと入力してみましたが、初期表示に設定できず。方法がわかったら追記しようと思います。）

## 追記
### 2025/01/09
ChromebookのLinuxでbrowse-liteを使用するときのセッティング方法を記事にしました。

https://qiita.com/tomot7/items/b60d0246dabc680c80bf
Gitの差分確認でVisualStudioのWinMerge連携時に「VisualStudioを使用する」を押してハマった話

## 環境
- Windows 10 Pro
- VisualStudio 2022

## 参考記事
https://note.nkmk.me/git-config-setting/

https://qiita.com/hijion/items/ae2cccebf5d28ff733f3

https://mebee.info/2020/09/04/post-17179/

## はじめに
VisualStudio上でGitの差分確認として「WinMerge」を設定していたが、「VisualStudioを使用する」というリンクを押した時にハマってしまったので自分への戒めとしてここに残そうと思います。

## 事象
- 「Visual Studioを使用する」を押して、差分ツールがVisualStudioのデフォルトが適用されてしまった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/1db06857-c95d-505c-cae6-93bebf15379c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/606ec4fc-fd82-7e24-3853-6f27267a09cb.png)
どうやって元に戻せばいいんや。。

- 自身が設定していた`.gitconfig`(定義ファイル)を確認するが、自分が設定したdiffツール(WinMerge)しかない。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/1bf48e4f-ac73-fb6f-0d40-a909d236268e.png)

- 差分ツールの先がローカルと記載されていたため、cdで対象のディレクトリ(.gitフォルダが初期化されているディレクトリ)へ行き、`git config --local --list`を実行してみると、`difftool`や`diff.tool`など、怪しい設定がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/dc2602e6-3b05-b370-302b-fbc825529861.png)

- 全部自分で`.gitconfig`に設定しているため、`diff`系のローカル設定を`git config --local --unset`コマンドで全て削除していく

```
> git config --local --unset diff.tool
> git config --local --unset difftool.prompt
> git config --local --unset difftool.vsdiffmerge.cmd
> git config --local --unset difftool.vsdiffmerge.keepbackup
```
- 再度、`git config --local --list`で、`diff`系の設定値が削除されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/174def39-0a16-7a78-d870-551c718426e2.png)

- VisualStudioを再起動後、元の状態に戻っていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/94cbdf5a-c335-0ac4-2fb2-c81961ecf635.png)
[baserCMS]4系でのsqlite利用時のコンテンツデータと修復機能


baserCMS4系において、sqlite利用時に以下の事象が発生します。mysql利用時は発生しません。

- ゴミ箱にひとつでもコンテンツが存在する状態でコンテンツを追加すると、コンテンツツリー構造に重複番号が追加され不整合が発生する
- コンテンツを削除した場合に、lft, rghtの両方に重複番号が追加され、かつ欠番が発生しコンテンツツリー構造に不整合が発生する
- コンテンツを複数個まとめて（例：フォルダ＋下位コンテンツ）削除した場合に、コンテンツツリー構造に不整合が発生する

上記が具体的にどういった影響が出るかというと、主に以下の症状に繋がります。

- A. コンテンツのURLが、本来あるべきURLにならず間違ったURLとして保存されている
	- コンテンツのURLが正しくないことで、公開側のパンくずリストが正しく表示されない
- B. コンテンツのレイアウトテンプレートが正しく適用されない＝レイアウトが正しく適用されない
	- コンテンツのレイアウトテンプレートに、親フォルダの設定が適用されない
- C. コンテンツの並び替えを行う際にエラーが起こることがある

baserCMSプロジェクト側にissue発行済みです。
baserproject/basercms https://github.com/baserproject/basercms/issues/2734


この問題に対して、sqlite利用時にコンテンツデータを修復できるツールを作成してあります。


## 想定している対象者
- baserCMSでウェブサイトを制作をしている方
- PHPer


## 修復ツール

- ContentsRepair: https://github.com/ecatchup/ContentsRepair
	- sqlite利用時に、コンテンツ管理のツリー構造で並べ替えがうまくいかなくなった場合に、ツリー構造の修復を試みるためのbaserCMS4系専用のプラグインです。 
		- 管理側 admin-second, admin-third 両対応
		- README に記載のあるようにシステム管理グループのユーザのみがツール画面利用可


### コンテンツデータ修復管理が提供する機能

- コンテンツデータの整合性をチェックする
	- 管理側ユーティリティ → ツリー構造をチェックする と同機能
- コンテンツデータの整合性を修復する
	- 不整合となっているコンテンツデータに対して修復を試みる
- コンテンツを削除した際に、ゴミ箱に入る動作を無効化する
	- ゴミ箱に入れる一次削除（論理削除）が、物理削除になる
	- baserの基本動作として、削除操作で「ゴミ箱に入ります」案内が出ますがそのまま削除となります
	- ※本機能は無効化できるようREADMEに手順を記載してあります

baserCMSでは、コンテンツデータの並び順管理にCakePHPのTreeBehaviorを利用しています。
修復内容はTreeBehaviorが持つリカバリー機構を用いてます。
https://book.cakephp.org/2.0/ja/core-libraries/behaviors/tree.html#id8

![sc_contents_repair.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26110/73d94759-535d-d0ce-292c-3ecf35258f41.png "sc_contents_repair.png")


#### コンテンツデータの整合性修復

baserCMSコアが持つユーティリティ内ツリー構造リセットと異なるのは、こちらは実行画面に記載のあるようにリセットを実行した場合、階層構造はリセットされます。
具体的には、フォルダの中に入っていたコンテンツが外に出され、階層構造ではなくなりクリーンな状態に修正することができます。

一方修復ツールでは、階層構造は可能な限り以前のままとなる仕組みとなっています。
ただし、コンテンツの並び順は既に破損状態にあるため順序の保証は不可能です。
また、修復ツールではコアのツリー構造リセットと異なり、現存するデータをもとに修復にトライするため実行負荷が高く、環境に依っては実行中にタイムアウトする等の動作が起こりやすいです。

よって、修復ツールでタイムアウトが起こり実行完了できない場合は、リセットを用いるというように使い分けると良いでしょう。
実行前に、コンテンツ一覧画面のスクリーンショットを撮っておくなどしてご利用ください。


#### コンテンツを削除した際のゴミ箱に入る動作を無効化

ゴミ箱機能を無効化するのは、SQLite＋SoftDeleteBehavior の組み合わせでの挙動に問題があるため、ゴミ箱機能で利用しているSoftDeleteを無効化することで、コンテンツデータの不整合発生を防止できるようにしてあります。

baserの基本動作として、削除操作で「ゴミ箱に入ります」案内が出ますが、こちらの機能は無効化できないためゴミ箱には入らずそのまま削除となります。
本機能は無効化できるようREADMEに手順を記載してあります。


### 参考

- https://github.com/baserproject/basercms/issues/2734
- https://forum.basercms.net/t/topic/1146
[Google Cloud]Colab EnterpriseのDuetAI支援でコーディングしてみる

## 概要
Google Cloud Next '23でColab Enterprise の公開プレビュー版が発表されたので試してみます。

https://cloud.google.com/blog/ja/topics/google-cloud-next/next-2023-wrap-up#:~:text=14.%20Google%20%E3%81%AF%E3%80%81%E3%81%9D%E3%81%AE%20Colab%20%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF%E3%81%AE%E4%BD%BF%E3%81%84%E3%82%84%E3%81%99%E3%81%95%E3%81%A8%E3%80%81%E3%82%A8%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%97%E3%83%A9%E3%82%A4%E3%82%BA%20%E3%83%AC%E3%83%99%E3%83%AB%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E6%A9%9F%E8%83%BD%E3%80%81%E3%82%B3%E3%83%B3%E3%83%97%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%82%B9%20%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E6%A9%9F%E8%83%BD%E3%82%92%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%9F%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%20%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%80%81Colab%20Enterprise%20%E3%81%AE%E5%85%AC%E9%96%8B%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E7%89%88%E3%82%92%E7%99%BA%E8%A1%A8%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82

#### ドキュメント
https://cloud.google.com/colab/docs/introduction

#### ブログ
https://cloud.google.com/blog/ja/products/ai-machine-learning/vertex-ai-colab-enterprise-and-mlops

## 使ってみる
コンソールのColab Enterpriseに移動してノートブックを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876448/0994f773-9948-4e89-d00c-15d23fba8d30.png)

Getting Startedのコードを実行するには右上の接続→ランタイムに接続をしてからコード左上の▶を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876448/79481427-acad-20e9-e63d-af7492035261.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876448/31b0107b-9413-d21e-003a-abd82c6070da.png)


## コード補完
特段設定をする必要なくコードの例が出てくる。
出てきたコードを利用する場合はTabを押す。

例：
![image.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876448/1270b78c-e377-0e8d-aab3-57c8201eb124.gif)

## おわりに
今回は簡単に機能を試すだけでしたが、今後しっかりと使っていく中で気になったことやTipsをアップデートして記載したいと思っています。
【Windows向け】VisualStudioの差分ツールにWinMergeを使う

## 環境
- Windows 10 Pro
- VisualStudio 2022

## 参考記事
https://takumi-oda.com/blog/2020/07/23/use-winmerge-on-visualstudio/

https://sevenb.jp/wordpress/ura/2018/11/27/visualstudio%E6%AF%94%E8%BC%83%E3%81%ABwinmerge%E3%82%92%E4%BD%BF%E3%81%86%E3%82%88%E3%81%86%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B/

## Gitのグローバル設定で差分ツールを変更
- `.gitconfig`ファイル(git定義ファイル)に以下の内容を追記して保存
```
# 差分ツールの設定(WinMerge)
[diff]
    tool = WinMerge
[difftool]
    prompt = true
[difftool "WinMerge"]
    path = C:/Program Files (x86)/WinMerge/WinMergeU.exe
    cmd = \"C:/Program Files (x86)/WinMerge/WinMergeU.exe\" -f \"*.*\" -e -u -r \"$LOCAL\" \"$REMOTE\"
# マージツールの設定(WinMerge)
[merge]
    tool = WinMerge
[mergetool]
    prompt = true
[mergetool "WinMerge"]
    path = C:/Program Files (x86)/WinMerge/WinMergeU.exe
    cmd = \"C:/Program Files (x86)/WinMerge/WinMergeU.exe\" -e -u \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
```

## 変更内容が反映されているか確認
-  VisualStudioを再起動後、[ツール]→[オプション]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/1d66d4f4-78cf-5953-0c27-9771b44b8f59.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/55700f48-7223-dbf5-49f7-8e767343c8af.png)

- [ソース管理]→[全般]を見ると以下のようにWinMergeが表示されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/f7ea4caa-883a-899c-bb8d-2d5df2960a78.png)

**「Visual Studioを使用する」は絶対に押さないでください**
※仮に「Visual Studioを使用する」のリンクを押した場合は以下の記事で修正してください

https://qiita.com/inakuuun/items/621383d3e901e3b68813
MacでEmacs風の長方形(短形)選択は「Option + マウス範囲選択」で可能

# はじめに

Emacs のメリットの１つは、短形選択、長方形選択、ができることだと思ってましたが、Mac だと、「Option + マウス範囲選択」 で簡単にできます。

https://qiita.com/yamadasuzaku/items/77a6af0fe628f71e6b8f#2-sublimetext%E3%81%A7%E3%82%82%E9%95%B7%E6%96%B9%E5%BD%A2%E9%81%B8%E6%8A%9E%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99

で、SublimeText ではできますよ、という紹介をしましたが、、CotEditor でも、JupyterLab でもできますね。

## 使い方

特別に新しい情報ではないので、上記のページや、

http://inforati.jp/apple/mac-tips-techniques/system-hints/how-to-select-text-in-rectangle-in-mac.html#:~:text=%E9%80%9A%E5%B8%B8%E3%80%81%E3%83%9E%E3%82%A6%E3%82%B9%E3%82%92%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%E3%81%97,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

など、記載があるように、「Option + マウスで範囲選択」で長方形で選択できます。
Salesforceで商談フェーズの小ネタ

こんにちは
本橋孝昭です

今回はSalesforceの商談フェーズの考え方について示します

商談オブジェクトのそのほかの内容はこちらをご確認ください

https://qiita.com/Takaa/items/4134ebfb4adc67d1d203

Salesforceの商談オブジェクトの考え方は「商談フェーズ」の考え方が重要です
しかし商談フェーズが特定のフェーズに遷移する前に特定の項目を入力したい
ということがよくあります
その際に設定するが「パス」設定です

パスを使うためにはまずはパスの有効化が必要です

「パスの有効化」をクリックして有効にしましょう

![パス有効化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ef390e38-bfe0-3a8c-800e-66814856f98e.png)

その後パスの作成をします。
１レコードタイプに１パスしか作成できないのでご注意ください

![商談パス1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fc7a7ed3-f47f-3c0d-e54a-d835d0368349.png)

パス設定では項目追加やそのパスでの文字記載が可能です

![パス設定３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/3e0b2573-88a3-9225-5cdc-ea4c5deea2f0.png)


このように設定すると、特定フェーズの場合特定項目を表示させることが可能なので、フェーズ移行時に重要な項目を逃す心配はなくなります
![パス設定４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7221589c-59ce-9ecf-54a0-775c31ae6d16.png)



※余談※
商談フェーズ変更時によくある課題として
・パスを戻さないようにしたい

という内容があります

ここについては、Salesforceのヘルプによると入力規則の設定で対応可能です


営業担当による商談フェーズの後退の禁止
項目	値
説明:	カスタム承認プロセスを介して商談を受け付けた後に、営業担当が商談 [フェーズ] を「後退」させることを防ぎます。承認プロセスでは、カスタム [承諾フラグ] チェックボックスが「True」に設定されます。
数式:	
AND(
   Accepted_Flag__c,
   OR ( ISPICKVAL( StageName, "Stage 1"), ISPICKVAL( StageName, "Stage 2"))
)
エラーメッセージ:	受け付けた商談には指定できないフェーズです。
エラー表示場所:	フェーズ


https://help.salesforce.com/s/articleView?id=sf.fields_useful_validation_formulas_oppty_mgmt.htm&type=5
シェルコマンドでKEY、VALUE形式のファイルから値を取得する方法

シェル（Bash）でKEY、VALUE形式のファイルから値を取得する方法を紹介します。

# 1. コメント、空行を外すコマンド

`cat <ファイル名> | grep -v '^\s*$' | grep -v '^\s*#'`
または
`grep -v -e '^\s*$' -e '^\s*#' <ファイル名>`

+ grepの`-v`オプションは一致するものを除外
+ 正規表現の`^`は行の先頭
+ 正規表現の`$`は行の末尾
+ 正規表現の`s`は空白文字（半角スペース、\t、\n、\r、\f）
+ 正規表現の`*`は直前のパターンの0回以上の繰り替えし

実行例は以下の通りです。
```conf:test.conf
# comments
key01=value01
key02=value02
   #key02=value02
key03=value03
key04=value04

key05=value05
```

```console:実行例（１）
[root@centos85 ~]# cat test.conf | grep -v '^\s*$' | grep -v '^\s*#'
key01=value01
key02=value02
key03=value03
key04=value04
key05=value05
[root@centos85 ~]#
```

```console:実行例（２）
[root@centos85 ~]# grep -v -e '^\s*$' -e '^\s*#' test.conf
key01=value01
key02=value02
key03=value03
key04=value04
key05=value05
[root@centos85 ~]#
```

# 2. KEY値で検索

`cat <ファイル名> | grep -v '^\s*$' | grep -v '^\s*#' | grep <検索するKEY値>`
または
`grep -v -e '^\s*$' -e '^\s*#' <ファイル名> | grep <検索するKEY値>`

```console:実行例（１）
[root@centos85 ~]# cat test.conf | grep -v '^\s*$' | grep -v '^\s*#' | grep key02
key02=value02
[root@centos85 ~]#
```
```console:実行例（２）
[root@centos85 ~]# grep -v -e '^\s*$' -e '^\s*#' test.conf | grep key02
key02=value02
[root@centos85 ~]#
```

# 3. `=`で分割し2項目目を取得しVALUE値を取得
`cat <ファイル名> | grep -v '^\s*$' | grep -v '^\s*#' | grep <検索するKEY値>　| cut -d "=" -f 2`
または
`grep -v -e '^\s*$' -e '^\s*#' <ファイル名> | grep <検索するKEY値> | cut -d "=" -f 2`

+ cutコマンドの`-d`オプションで`=`で分割
+ cutコマンドの`-f`オプションで`2`項目目を取得

```console:実行例（１）
[root@centos85 ~]# cat test.conf | grep -v '^\s*$' | grep -v '^\s*#' | grep key02 | cut -d "=" -f 2
value02
[root@centos85 ~]#
```
```console:実行例（２）
[root@centos85 ~]# grep -v -e '^\s*$' -e '^\s*#' test.conf | grep key02 | cut -d "=" -f 2
value02
[root@centos85 ~]#
```

<font color="red">**KEY値を指定して、VALUE値を取得することができました。**</font>

# 4. その他
`sed`コマンドを使って置換して、KEY値からVALUE値を取得することもできます。

`cat test.conf | grep -v '^\s*$' | grep -v '^\s*#' | grep "key02" | sed -r s:'key02='::`

```console:実行例
[root@centos85 ~]# cat test.conf | grep -v '^\s*$' | grep -v '^\s*#' | grep "key02" | sed -r s:'key02='::
value02
[root@centos85 ~]#
```

---
以上
ゲストログイン機能

ポートフォリオを作成するにあたってお試しで使いやすくするために、ゲストログイン機能を作成しました。

参考記事：[簡単ログイン・ゲストログイン機能の実装方法（ポートフォリオ用）](https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104)


（１）ルーティングに記述。
```
devise_scope :user do
  post 'users/guest_sign_in', to: 'users/sessions#guest_sign_in'
end
```

（２）「guest_sign_in」アクションを設定するため、「session_controller.rb」を作成し記述。
sign_in user でユーザーとしてログイン。
```
def guest_sign_in
  user = User.guest
  sign_in user
  redirect_to posts_top_path
end
```

（３）ゲストユーザーを作成するメソッドをUser.rbに記述。
- 「find_or_create_by」はデータを自動検索し、条件に該当したデータがあればデータの値を返し、存在しなければ新規作成するRailsのメソッド。
- 今回はパスワードを6文字以上～12文字以内で作成するように制限をかけているので「SecureRandom.urlsafe_base64」にてランダムな文字列を作成する上で6文字で作成できるように文字数を指定。

```
def self.guest
  find_or_create_by!(email: "guest@example.com")
  user.password = SecureRandom.urlsafe_base64(6)
　user.name = "ゲスト"
　user.account_id = "guest123"
end
```
Reactのテストがなんか失敗してしまう

## はじめに
はじめてReactのテストを書く中で、ちゃんと書いているはずなのになぜか失敗してしまうことがあったので、そのことについて書いておこうと思います。
（超基本的なところなので、悪しからず。。）

## 躓いたポイント
 - テストがタイムアウトになって失敗してしまう
 - Inputフィールドで値をクリアにしているにも関わらず、クリアされていない（想定外の値が入っている）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/1debc0c8-8395-ef2d-eb20-ce5e483aff47.png)


テストの書き方が良くないのかと思って調べてみるのですが、よさそうな解決法が出てこず。。

## 何が悪かったのか
上記で起きた内容はどちらも同じことが原因となって起きていたということがわかりました。
とても単純な話ですが、Promise<void>が戻り値の型として返ってくるのにawaitを書き忘れていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/01590538-70f4-d12f-d9a1-f24b1bd44a52.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3057699/b0eafc03-054b-8308-2747-2fa94a5034f6.png)
それによって処理が正しく行われずエラーになってしまっていました。

## おわりに
すごく単純なミスでうまく動かないこともあるので、ただ動くからOKではなくちゃんと意図した書き方になっていることを確認する必要があるということを再認識しました。

ESLintにはawaitの書き忘れを防ぐためのルールもあるようなので、こういったものも積極的に使っていきたいと思います。
https://eslint.org/docs/latest/rules/require-await
BlenderからインポートしたアニメーションをUnity上で編集する方法

Blenderからインポートしたアニメーションは、Unity内で直接編集することができません。これは、インポートされたアニメーションクリップがRead-Onlyモードになっているためです。ただし、以下の方法で回避して、アニメーションを編集することができます。

### 1. アニメーションの複製

インポートされたアニメーションクリップを複製して、複製されたクリップを編集します。

1. Projectウィンドウでインポートされたアニメーションクリップを選択します。
2. Ctrl+D (Windows) または Cmd+D (Mac) を押して、アニメーションクリップを複製します。
3. 複製されたアニメーションクリップを選択し、Inspectorウィンドウで名前と設定を変更します。

### 2. Animation Override Controller の使用

Animation Override Controller を使用して、特定のアニメーションクリップを別のものにオーバーライドします。

1. Projectウィンドウで右クリックし、"Create" > "Animator Override Controller" を選択します。
2. 新しく作成された Override Controller を選択し、Inspectorウィンドウで基本となる Animator Controller を設定します。
3. アニメーションクリップのリストが表示されるので、オーバーライドしたいアニメーションをドラッグアンドドロップしてリプレースします。

### 3. アセットのリエクスポート

Blenderでアニメーションを編集し、改めてUnityにインポートする方法もあります。

1. Blenderでアニメーションを開き、必要な変更を加えます。
2. アニメーションをFBXなどの形式で再エクスポートします。
3. Unityに戻り、新しいアセットをインポートまたは既存のアセットを更新します。

### 4. Playables APIを使用する

Playables APIを使用して、ランタイムでアニメーションクリップのプロパティやイベントを動的に変更することができます。これはより高度な方法であり、プログラミングの知識が必要です。

これらの方法を試して、BlenderからインポートしたアニメーションをUnity内で編集してください。それぞれの方法が異なるシチュエーションやニーズに適しているため、最適な方法を選んで利用すると良いでしょう。
【Tailwind CSS】個人用チートシート


# Introduction

個人開発をする際にTailwind CSSをよく使うのですが、簡単な実装でも調査に時間を費やすことが多くありました。
本業がMLエンジニアのためWebに疎く、時間が経つと記憶から抜け落ちてしまいます。。。
本記事ではTailwind CSSで個人的に頻繁に使う or 忘れがちな実装をメモしていきます。

慣れており、様々な機能を使いこなせる方は公式のチートシートが充実していて大変素晴らしいです。

https://tailwindcomponents.com/cheatsheet/

また、Tailwind CSSはテンプレートも充実しています。
特に私はPreline UIをよく使うので紹介しておきます。
[![Preline UI](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106716/7b2a93f2-5bfe-90dc-963c-7df5f0c54a88.png)](https://preline.co/)

:::note info
Information:
Tailwind CSS v3の内容を記載します。
:::

**本記事が少しでも読者様の学びに繋がれば幸いです！**
**「いいね」をしていただけると今後の励みになるので、是非お願いします！**

## 環境

Ubuntu22.04
tailwindcss@3.3.3

## チートシートメモ

| 期待事項               | 実装                           |
| :--------------------- | :----------------------------- |
| 横並びにしたい         | flex items-center              |
| 改行したくない         | whitespace-nowrap              |
| レスポンシブ対応したい | sm @media (min-width: 640px)   |
|                        | md @media (min-width: 768px)   |
|                        | lg @media (min-width: 1024px)  |
|                        | xl @media (min-width: 1280px)  |
|                        | 2xl @media (min-width: 1536px) |
| 文字を左右反転したい   | transform scale-x-[-1]         |
| フッターを固定したい   | flex flex-col min-h-screen     |

:::note info
Information:
随時追加予定。
:::

### 最後に

最後まで閲覧頂きありがとうございました。
本記事がお役に立てば幸いです！

### 参考URL

https://tailwindcomponents.com/cheatsheet/

https://preline.co/
UnityのScript Execution OrderとDefaultExecutionOrderの違いと使い方

Unityでゲーム開発を進めている際、スクリプトの実行順序を制御する必要が出てくることがあります。この記事では、Script Execution OrderとDefaultExecutionOrderの2つの異なる方法について詳しく解説します。

### 1. Script Execution Order

Script Execution Orderは、Unityエディタから直接、スクリプトの実行順序を設定する方法です。これを使用すると、特定のスクリプトが他のスクリプトより先に、または後に実行されるよう手動で設定することができます。

#### 特徴
- GUIを介して設定するため、視覚的にわかりやすい。
- エディタレベルでの設定のため、コードを変更する必要がない。

#### 設定方法
1. Unityエディタのメニューバーから [Edit] > [Project Settings] を選択。
2. [Script Execution Order] パネルを開く。
3. [+ Add] ボタンで新しいスクリプトを追加し、ドラッグアンドドロップで順序を変更。

### 2. DefaultExecutionOrder

DefaultExecutionOrderは、スクリプトに属性を追加して実行順序を指定する方法です。この属性を使用すると、コードレベルでの細かい制御が可能になります。

#### 特徴
- スクリプト内で直接実行順序を設定するため、柔軟に制御できる。
- 複数のプロジェクトで同じスクリプトを使用する場合に便利。

#### 設定方法
スクリプトに`[DefaultExecutionOrder(order)]`属性を追加するだけです。`order`には整数を指定し、数値が小さいほど早く、数値が大きいほど遅く実行されます。

```csharp
using UnityEngine;

[DefaultExecutionOrder(-100)]  // 他のスクリプトより先に実行
public class MyFirstScript : MonoBehaviour
{
    // ...
}
```

### まとめ

- Script Execution Orderは、エディタ上でグラフィカルにスクリプトの実行順序を設定する場合に便利です。
- DefaultExecutionOrderは、コードレベルでスクリプトの実行順序を制御する必要がある場合、特に複数のプロジェクト間でスクリプトを共有する場合に有効です。

それぞれの制御方法には利点と欠点があるため、プロジェクトの要件に応じて最適な方法を選択してください。
最新の「デジタルビジネス」に関する情報をお届け

Brand New Biz | デジタルビジネス最新情報メディア

https://brandnewbiz.net/

最新の「デジタルビジネス」に関する情報をお届けするWebメディア【Brand New Biz 】。AI、IoT、デジタルマーケティング、サステナビリティ、ウェルビーイング、DXなどの情報を【海辺の部屋】がお届けします。


著者名：【海辺の部屋】メディアチーム 

【海辺の部屋】は経済産業省から「IT専門家」の認定を受け、40社以上から業務を依頼されてきた『デジタルマーケティング』のスペシャリストです。高い倫理観を持ったデータ活用、個人情報の適切な管理、サステナビリティを重視した「人に優しい世界」を目指しています。『マーケティングは愛である』をモットーにしています♪ 

【資格等】：NewsPicksビジネスエキスパート、中小企業デジタル化応援隊、介護職初任者研修、日本医療事務協会認定保険請求技能検定試験、JASRAC会員、診療報酬請求事務能力認定試験

＜カテゴリー＞

・DX
https://brandnewbiz.net/?cat=3

・SNS
https://brandnewbiz.net/?cat=14

・クラウド
https://brandnewbiz.net/?cat=11

・グローバル企業
https://brandnewbiz.net/?cat=15

・サステナビリティ
https://brandnewbiz.net/?cat=22

・ビジネス・スキル
https://brandnewbiz.net/?cat=74

・マーケティング
https://brandnewbiz.net/?cat=9

・企業経営
https://brandnewbiz.net/?cat=33

・日本企業
https://brandnewbiz.net/?cat=27


＜SNS＞

Twitter：
https://twitter.com/BrandNewBiz24

Instagram：
https://www.instagram.com/bnbiz24/

Pinterest：
https://www.pinterest.jp/brandnewbiz/

note：
https://note.com/bnbiz

運営者：海辺の部屋
https://www.umibe.art/

STAND WAVE web site：@可児波起 - ラッパー - 歌い手 - 作詞家 - 作曲家
https://standwave.jp/
Docker エラー

下記エラー
ERROR(): Provision failed - ProvisioningError: guess_names: 'realm =' was not specified in supplied /etc/samba/smb.conf. Please remove the smb.conf file and let provision generate it File "/usr/lib/python3/dist-packages/samba/netcmd/domain.py", line 493, in run result = provision(self.logger, File "/usr/lib/python3/dist-packages/samba/provision/init.py", line 2231, in provision names = guess_names(lp=lp, hostname=hostname, domain=domain, File "/usr/lib/python3/dist-packages/samba/provision/init.py", line 625, in guess_names raise ProvisioningError("guess_names: 'realm =' was not specified in supplied %s. Please remove the smb.conf file and let provision generate it" % lp.configfile)

このエラーメッセージは、Sambaの設定ファイル（smb.conf）の生成中に問題が発生していることを示しています。特に、smb.confファイル内で 'realm =' パラメータが指定されていないことが指摘されています。

この問題を解決するために、以下の手順を実行してみてください：

1. smb.confファイルを削除します：

   ```
     rm /etc/samba/smb.conf
   ```

2. provisioning（プロビジョニング）プロセスを再実行します。具体的なコマンドは、Sambaをどのようにプロビジョニングしているかに依存しますが、次のようなコマンドを使用するかもしれません：
   ```
     samba-tool domain provision
   ```
   または
   ```
      samba-tool domain join
   ```

   プロビジョニングコマンドを実行する際に、必要なパラメータ（レルム名やドメイン名など）を指定してください。これにより、正しい設定で新しいsmb.confファイルが生成されます。

3. プロビジョニングが成功したら、新しいsmb.confファイルを確認して、'realm ='パラメータが正しく設定されていることを確認してください。

これにより、お使いのSambaのプロビジョニングエラーが解決し、Sambaを正しく構成できるはずです。
Dockerイメージ削除の際

イメージ削除の際、以下のようなエラーが出る

Error response from daemon: conflict: unable to remove repository reference "ubuntu" (must force) - container 878e78a6f0bf is using its referenced image c6b84b685f35

以下を参考
https://qiita.com/gisuyama7/items/82086b30f6b8e6fc14cf
Visual Studio拡張機能

## 環境
- Windows 10 Pro
- VisualStudio 2022

## 参考記事
https://qiita.com/HnniTns/items/5da671d6a9cb002eb25d

## はじめに
Visual Studioの拡張機能を導入しながら、備忘録として残しておきたいと思いここに記すことにしました。拡張機能を入れるたびに都度都度更新していこうかなと思います。

## 導入した拡張機能
#### Solution Error Visualizer

https://marketplace.visualstudio.com/items?itemName=VisualStudioPlatformTeam.SolutionErrorVisualizer2022
- エラーのあるファイルを強調してくれる拡張機能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/3c8890b2-13c1-85f7-5f6b-bba62ba52b6e.png)
Spring


- SpringBoot、SpringFrameworkなどをすべて含む**Spring生態系**、つまり様々な技術の集合である。
- SpringBootを通じてSpringFrameworkの技術を便利に使用している。

<br/>
以下の写真以外にもより多くの種類がある。 https://spring.io/project

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/a7cfa3fd-bfb2-dba7-b3b8-a76b6239a4ce.png)
CSF2とCSF3の違いは？これからのComponent Story Formatを学ぶ

Storybookのバージョンが7に上がり、CSFの書き方も変わりました。
今後はCSF3で記述されることを考えると今CSF2を理解することはそれほど有意義ではないかもしれません…。

:::note info
CSF2で記述されているプロジェクトに関わることもあるかと考えて、「どうかわったのか？」をインプットしたいと思いました!
:::

## CSFとは何か？
改めて、CSFとは「Component Story Format」のことでReactコンポーネントを文書化するための形式のことです。
現在ではStorybookのバージョンが変わりCSF2よりもCSF3の利用が推奨されています。

## CSF2とCSF3で何が変わったのか？
主な変更点は2点で
- コンポーネンの定義が簡素化されてシンプルに記述できるようになった
- TypeScriptとの互換性が上がった

シンプルなコンポーネントを作成してみました。
実際のコードで比較したいと思います！

### CSF2で記述した例
```tsx
import React from 'react';
import { storiesOf } from '@storybook/react';
import Card from './card';

const meta = {
  title: 'Components/Card',
  component: Card,
  parameters: {
    layout: 'centered',
  },
  tags: ['autodocs'],
  argTypes: {
    title: { control: 'label' },
  },
};

storiesOf(meta.title, module)
  .add('card', () => (
    <Card
      title="cardにheadingを設定したいときに入力してください"
      children="cardのコンテンツをここに入れます。HTMLなども入れることも自由に入れることができます"
    />
  ));

```

### CSF3で記述した例
```tsx
import type { Meta, StoryObj } from '@storybook/react';
import Card from './card';

const meta = {
  title: 'Components/Card',
  component: Card,
  parameters: {
    layout: 'centered',
  },
  tags: ['autodocs'],
  argTypes: {
    title: { control: 'label' },
  },
} satisfies Meta<typeof Card>;

export default meta;
type Story = StoryObj<typeof meta>;

export const card: Story = {
  args: {
    title: 'cardにheadingを設定したいときに入力してください',
    children:
      'cardのコンテンツをここに入れます。HTMLなども入れることも自由に入れることができます',
  },
};
```

### CSF2とCSF3のコードの違い

#### import箇所
CSF2では`storiesOf`関数をインポートしてストーリーを定義する際に利用しています。
それに対しCSF3は、`@storybook/react`からtypeで指定して型情報のみをインポートしています。

#### metaデータの定義
今回の記述方法だとmetaデータ定義部分ではほとんど差はありませんが、最後の1行が異なっています。

```jsx
 } satisfies Meta<typeof Card>;
```

上記のように記述しておくことでCSF2では検知できなかった必須引数の不足をエラーとして検知してくれます。

#### storyの定義
CSF2ではstoryの定義時に`storiesOf`関数を利用して定義するのに対して、CSF3では名前つきエクスポートを利用することで完結にstoryを定義することができます。


## 【CSF2とCSF3の違い】まとめ
シンプルに記述できるようになったのも素晴らしいですが、TypeScriptとの互換性が上がったことで開発中のミスに気がつけるようになったのは開発体験があがるだけでなく、コードの保守・運用の面でも役立つイメージをもてました！

まだまだ、理解できていない利点はあると思いますがさらに知見を深めていきたいと思います！
EC2 SSH鍵 なくした

https://repost.aws/ja/knowledge-center/user-data-replace-key-pair-ec2

- 方法1: [ユーザーデータ](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html)を入力する
    - 再起動したときに読み込まれて公開鍵を登録し直したりできる？
    - [参考](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instancedata-add-user-data.html)
- 方法2: [AWS Systems Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html)
    - 前提: [マネージドインスタンス](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/managed_instances.html)である必要がある
    - 鍵紛失以外の原因でSSHできなくなった場合は対応できるかは知らない
- 方法3: [EC2 Instance Connect](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-connect-methods.html)
    - [前提](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-connect-prerequisites.html): AMIにEC2 Instance Connectが**入ってること**。AmazonLinux2以降とかだと最初からある
    - 前提: [AWSのIP範囲](https://ip-ranges.amazonaws.com/ip-ranges.json)のEC2_INSTANCE_CONNECTのとこのIPを**セキュリティグループで許可**する必要がある
    - プライベートなEC2だと接続できないので[EC2 Instance Connect Endpoint](https://dev.classmethod.jp/articles/demystifying-ec2-instance-connect-implementation/)を利用する？
    - rootで入れる（はず）
- 方法4: [EC2 Serial Console](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-serial-console.html)
    - 前提: **[専用の権限](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/configure-access-to-serial-console.html)を許可**する必要がある
    - 前提: インスタンスの種類などに制限あり [詳細](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-serial-console-prerequisites.html)
    - この方法だけ**停止の必要がない**らしい
    - [rootユーザの設定](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/configure-access-to-serial-console.html#set-user-password)ができたりするらしい
    - sshdがぶっ壊れてても接続できる。のがシリアルコンソール（[参考](https://gihyo.jp/admin/serial/01/bsd-yomoyama/0022)）
    - ブラウザベースのクライアントあり


↓シリアルコンソールの詳細な手順 :thumbsup: 

https://qiita.com/sakai00kou/items/9d1a474ae24ce6d2d242

https://qiita.com/hirosys-biz/items/2759cfe7183b62cfbc97
kintone 開発者ライセンスを取得する

# kintone 開発者ライセンスの取得

[こちらの申し込みフォームから申し込み](https://cybozu.dev/ja/kintone/developer-license/registration-form/)

会社名、氏名、メールアドレスなどを入力します。

[利用規約を確認しておきましょう](https://cybozu.dev/ja/kintone/developer-license/terms-of-service/)

[申し込む] ボタンをクリック。
![l_1517737_2969_449481f65d87bdb455e7de86f7809eaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/bb4defef-42ed-1369-a238-c96672170eae.png)

申し込みが完了します。
![l_1517737_2967_5dbe0838f05974b2b1b1e8e75ce53938.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/171feb60-77ea-a9b7-3fb1-f244147be94e.png)

しばらくするとメールが届きます。
記載の手順に沿って kintone 開発者環境にアクセスしましょう。
![l_1517737_2968_4b51570892c2570dfbfe8c583bb2c5bf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/45c6b4ae-a93e-9cd1-5ace-1a744201fcfd.png)
Android Studio: Navigation Drawer Views Activity を使う

テンプレート Navigation Drawer Views Activity を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e3016871-3574-029d-a28b-062ffa3a3d92.png)

このままでは、Build ができません。

build.gradle.kts　を修正します。

>33 -> 34
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/94fa58c7-90d3-83dc-af78-07deb709256d.png)

```text:build.gradle.kts
（省略）
compileSdk = 34
（省略）
targetSdk = 34
（省略）
```

## res -> values -> strings.xml の修正

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/ba4f3353-99bc-20f2-522a-805839759826.png)


```xml:res/values/strings.xml
<resources>
    <string name="app_name">example05</string>
    <string name="navigation_drawer_open">Open navigation drawer</string>
    <string name="navigation_drawer_close">Close navigation drawer</string>
    <string name="nav_header_title">Android Studio</string>
    <string name="nav_header_subtitle">android.studio@android.com</string>
    <string name="nav_header_desc">Navigation header</string>
    <string name="action_settings">Settings</string>

    <string name="menu_home">ホーム</string>
    <string name="menu_gallery">ギャラリー</string>
    <string name="menu_slideshow">スライドショー</string>
</resources>
```

## java -> com.example.example05 -> ui の修正

gallery -> GalleryViewModel
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/bfacae55-3208-fbef-703a-fd21b5f61681.png)

```text
value = "これはギャラリーです。"
```

home -> HomeViewModel
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a42b95c9-1b05-ad8b-5dbd-142e03dc1c6d.png)

```text
value = "これはホームです。"
```

slideshow -> SlideshowViewModel
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c8a1ddc6-1274-e4b8-2ba3-10fec1e17db4.png)

```text
value = "これはスライドショーです。"
```

## Run
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/433f7000-380b-d2d4-89d2-26a3ac12722e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/8fb87765-5759-041f-fa7e-8cefa3d1a092.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/97eb1be2-51c3-5624-0edc-7f65c66548c4.png)

## 実機での動作確認

app-debug.apk を USB 経由で、アンドロイドタブレットに持っていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d83ead89-ec6a-a29b-4b84-13fdafcf947b.png)

実行時の様子
![android02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4713134f-0cae-46ef-2680-530ac32b5d1b.png)
【VScode】Shift+Enterでカーソルを右に移動させる

# 初めに
コード編集中にカーソルを右移動させたいとき、いちいち→キーを押しに行くのが手間なので「Shift+Enter」で右移動する方法を記載します。

# 方法
画面上部の検索欄から「> keyboard」と検索すると
「Preferences: Open Keyboad Shortcuts(JSON)」
と出てくるので、これを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183099/981d705f-cdfe-aec3-48aa-31d020a4d416.png)

keybindings.jsonが開かれるので下のような設定を書き込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183099/944960da-58c9-bf06-fee8-d9490151f378.png)

これを保存して終了です。
（場合により再起動が必要かもしれません）
【Laravel】複雑な条件でのバリデーション追加

今回は入力値によってバリデーションを分けて表示させたいときの方法について説明します。

一般的なバリデーションの方法についてはこちらの記事を参考にしてください。
https://qiita.com/tomoki1616/items/e344a239ba5e0eac4de3

開発環境
・PHP8.0.8
・Laravel 9.52.8
・MacOS M1チップ

## 今回やりたいこと
今回やりたいことはユーザーの入力値によってバリデーションを分ける方法です。
例えばAと入力された場合には必須項目とし、Bと入力された場合には任意項目とするみたいな感じです。
複雑なバリデーションに慣れておくことで複雑なシステム開発が可能になります。

## withValidatorを使う
複雑な条件下でバリデーションを分けたい場合は``withValidator``を使いましょう。
``withValidator``は通常のバリデーション後にバリデーションを追加したいときに便利です。
```php:samleFormRequest.php
namespace App\Http\Requests;

use Illuminate\Validation\Validator;

class samleFormRequest extends FormRequest
{

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules():array
    {
        return [
            'name' => 'nullable|max:255',
            'type' => 'nullable|integer'
          ];
    }

    public function withValidator(Validator $validator) {
        $validator->sometimes('name', 'required', function() {
        //typeが1だった場合
        return $this->input('type') == 1;
        });
    }
}
```
``type``が1の場合に``name``にバリデーションを追加したい場合は上記の書き方になります。
``sometimes``の引数として項目、追加したいバリデーション、その条件となります。

参考URL：https://readouble.com/laravel/8.x/ja/validation.html

## 注意するべきこと(失敗例)
注意するべきことは処理の流れです。
``withValidator``は通常のバリデーションの後に処理されるなので、下記のような場合は上手く動作しません。

```php
    public function rules():array
    {
        return [
            'name' => 'required|max:255',
            'type' => 'required|integer'
          ];
    }

    public function withValidator(Validator $validator) {
        $validator->sometimes('name', 'nullable', function() {
        //typeが1だった場合
        return $this->input('type') == 1;
        });
    }
```
問題は``required``と``nullable``を逆にしていしまっているためです。
先ほども言った通り、``withValidator``は通常のバリデーションの後に処理されるので未入力で送信したい場合は``required`` でバリデーションにはじかれてしまいます。
こうならないためにも最初を``nullable``、``withValidator``には``required``と記載しましょう。

## まとめ
バリデーションは運用面で必ず必要になってくる処理の一つです。
複雑な条件下でのバリデーションにも対応できるようにしておくことで、さまざまなシステム開発が可能になります。
僕も勉強した内容を発信していくので、一緒に勉強していきましょう！
Linuxでカレントディレクトリの編集権限を与える方法

ファイルやディレクトリに権限を与えるコマンドをよく忘れてしますので備忘録です。

```
chmod 777 ./
```

777は所有者・所有グループ・その他にそれぞれ7の権限を与えています。
権限は

|数字|文字|権限|
|---|---|---|
|4|r|読み取り|
|2|w|書き込み|
|1|r|実行|

の数字の足し算で割り当てられます。つまり7は読み取り・書き込み・実行の権限を持っているということです。

サブディレクトリすべてに権限を振りたい場合は
```
chmod -R 777 ./
```
とすればOKです。
GCPのVM上で構築したFastAPIを外部PCからコールする

GCPのVMでAPIを作成し、外部に公開したかったので、その手順をまとめました。
APIはFastAPIを利用して作成します。
APIの作成方法は詳しく触れませんので他の記事を参照してください。

# 目次
1. GCP上にVM（GCE）を構築し、APIを作成する。
2. GCPのファイアーウォールの設定をする。
3. 外部PCからAPIをコールする。

# 1. GCP上にVM（GCE）を構築し、APIを作成する。
- **VMの作成**

まず、GCP上にVMを作成します。
スペックを求めなければ無料で作成できます。
[こちら](https://se-abeaver.com/gcp-free-tier/)を参照してください。

特別な設定などは必要ありませんが、外部IPを固定しておくと今後便利です。
pythonはインストールしておいてください。

- **APIの作成**

以下のコードを任意のディレクトリに作成し、実行してください。
```python:main.py
from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get("/")
async def root():
    message = "Hello"
    return message

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
```

ホストを0.0.0.0/0にし、port番号8000に穴をあけています。
「手順2. GCPのファイアーウォールの設定をする。」でここへの外部からのアクセス許可を設定します。

実行すると以下のようにターミナルに出力されます。
```
$ python main.py
INFO:     Started server process [56297]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
```

# 2. GCPのファイアーウォールの設定をする。

GCPコンソール上で、左上のメニュー＞VPC ネットワーク＞ファイアウォール　からファイアウォールルールを作成することができます。

以下のように設定します。
ここで、任意のアドレス(0.0.0.0/0)から8000番ポートへのアクセスを許可しています。
セキュリティを高めたい方はアドレスを絞ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183099/6ec791a8-7b62-d443-116c-c59c1000a2b0.png)

ここで作成したターゲットタグ(fastapi)をVMで設定します。
VMインスタンスの設定で、ネットワークタグを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183099/d738fd3b-3081-b7e5-ea3d-abc477e06f1e.png)

# 3. 外部PCからAPIをコールする。

以上で準備が整いましたので、いよいよAPIをコールします。
ブラウザ上でhttp://[VMの外部IPアドレス]:8000と入力します。

"Hello"

と表示されれば完了です。
【XcodeCloud】XcodeCloudで実行した時はBuildPhasesのRunScriptを実行したくない

# はじめに
SwiftLintをRunScriptでビルドしてたのですが、XcodeCloudでの実行時間がめっちゃ長くなっちゃうので、
XcodeCloudで実行された時は処理をスキップしたいことがありました。
その時にRunScript上でXcodeCloudで実行されていることを検知する環境変数を知ったので記事にしておきます。

# 実装
```sh
if [ "$CI_XCODE_CLOUD" == "TRUE" ]; then
  echo "✅ XcodeCloudで実行されました"
else
  echo "❌ XcodeCloud以外で実行されました"
fi
```

これを使ってXcodeCloudの時は処理をスキップしたい時はこうなります。

```sh
if [ "$CI_XCODE_CLOUD" == "TRUE" ]; then
    exit 0
fi

# 行いたい処理
```

# おわり
XcodeCloudの実行時間が15分 → 3分に短縮されました！

# ドキュメント
https://developer.apple.com/documentation/xcode/environment-variable-reference
TortoiseGitとは、実際に導入してみたので良さを語る

## はじめに
3年目現役エンジニアですが、現場のバージョン管理ツールがGitではなく、SVNを使っているため、普段はTortoiseSVNを使っています。しかし、家で開発する時はGitを利用しているので、今回初めてTortoiseGitを導入してみました。操作感はほとんど変わらないため、TortoiseGitの良さを伝えられるかなと思い記事にしました。最後まで見ていただけると幸いです。

## TortoiseGitとは
GitはCUI(コマンド)で操作するのが一般的ですが、そのようなGit操作をGUI(マウスなど)で操作し、コミットの取り消しや差分などを確認する手間などを省くことができるツールです。
TortoiseGitをインストールするには、以下の記事を参照ください。

https://qiita.com/inakuuun/items/d8e3a04b7f7a741e2c31

## TortoiseGitの良さ
- リポジトリの状態を一目で判断できる(個人的にはこれが一番恩恵大きいと思う)
「gitで握っているフォルダなのかわからない」「前回コミットし忘れていた気がする」といった悩みを一気に解消してくれます。
    - リポジトリ配下に変更がない場合＝緑色
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/482156f7-9d6c-0d47-2378-136d91accacf.png)
    - リポジトリ配下で変更がある場合＝赤色
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/f78b6608-f502-4ad7-61aa-4a9a3b6faa15.png)

- 変更の取り消しなどが簡単にできる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/80ad0434-33c3-0a03-936d-ed45decd120d.png)
`git reset`コマンドなどを実行しなくて済むため、手間が減ります。

- 「WinMerge」というWindowsにインストールできる差分確認ツールを併用するとログの差分を見やすく、すぐ確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/04813753-a356-2ae0-366a-e239e4fa5343.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/9befd07d-5ff5-e116-909c-4e035afeb054.png)

- 「WinMerge」をインストールしたい方は以下を参照してください。
「WinMerge」は差分確認ツールで、これまで使ってきた中で一番使いやすい印象。「WinMerge」はGitに限らず2つのファイルを選択するだけでも差分が見れるおすすめのツールなので入れておいて損はないかなと思います。(インストールも比較的簡単です)

https://tabalog.org/winmerge-download-install/

## TortoiseGitのデメリット
- GitHubとの連携を行う時などに、Linuxに比べて設定がややこしく、情報が少ない印象が多いです。GitHubとの連携も以下で解説しているので、TortoiseGitを導入した際は以下も一緒に参照していただけたらと思います。

https://qiita.com/inakuuun/items/dd832881b3fe0239eb9d

## さいごに
個人的にTortoiseGitは、「変更の取り消しや」「差分の確認」「編集有無の確認」「Visual Studioとの連携」などの要素がとても魅力的だったので、補助ツールとしてインストールした感じです。CLIとGUIを使い分けながらより快適なGitライフをみんなで歩んでいきましょう。
Android Studio: Bottom Navigation Views Activity を使う

テンプレート Bottom Navigation Views Activity を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/19b83b31-b8cd-2e55-1952-4e81f980d0cb.png)

このままでは、Build ができません。

build.gradle.kts　を修正します。
>33 -> 34

```text:build.gradle.kts
（省略）
compileSdk = 34
（省略）
targetSdk = 34
（省略）
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/69aacc17-6bff-0ce6-9e5a-af10f5927680.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/b3e3bac7-0045-1274-adcf-8286f87cfd74.png)

## 実機で実行した様子

APK ファイルを USB でアンドロイドタブレットに持っていって、インストールしました。

![android03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/37591e45-5906-68ab-79b1-64511a13b743.png)

## 改造

res -> values -> strings.xml を改造します。

```xml:app/src/main/res/values/strings.xml
<resources>
    <string name="app_name">example03</string>
    <string name="title_home">ホーム</string>
    <string name="title_dashboard">ダッシュボード</string>
    <string name="title_notifications">告知</string>
</resources>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/fa33b6a3-48ae-a186-8e7f-76344cd1b891.png)
freemysqlhosting.netの照合順序に気をつけよう


使い始める前に照合順序を修正しよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/b75f6108-3f73-9e38-bdb3-167044235411.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/9533449f-61f5-afd7-f1c1-a6a157516601.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/6e3f97fb-3d04-7673-4da6-454d0309cff2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/4892ae95-f6de-f2dc-c033-a9d575e44440.png)


可能ならPDOも修正

```php
<?php
$pdo = new PDO(
    'mysql:host=yourhost;dbname=yourdb;charset=utf8mb4',
    'user', 'password'
);
```
lib/main.dart: Error: Error when reading 'lib/main.dart': No such file or directoryが出た時のxcodeでの対応方法

デフォルトではmain.dartがlib直下にある前提なので，main.dartの位置を変えるとこのようなエラーが出る．

Runner>Targets>Runner>BuildSettings>all&combined>User-Defined>FLUTTER_TARGETでmain.dartのパスを変更すればok
[リサーチ・メモ] jsonファイルの取り扱い

## 使用方法

```
  File file = new File(パス); //ファイルを読み取る
  ObjectMapper mapper = new ObjectMapper();
  JsonNode root = mapper.readTree(file); //特定のデータを抽出する為にJsonNode型に変換する
  int status = root.get("status").intValue(); //jsonファイルのkey:statusのvalueをint型で取得する
```
【Laravel】ReactでCSRFトークンを含めてフォーム送信する方法

LaravelでReactのコンポーネントを用いてフォーム送信を行いたい場合に、LaravelのCSRFトークンを含める方法について調べてみました。

## 何をしたいのか？
通常、Laravelでフォーム送信する際、CSRFトークンをリクエストに含める必要がある。
Laravel独自のテンプレートエンジンのBladeでは、<span>@</span>csrfディレクティブを利用することでCSRFトークンを生成することができる。

しかし、このフォーム送信をLaravel側ではなく、React側のコンポーネントの中で行いたい場合、どうすれば良いのだろうかと疑問に感じた。
そこで、今回はReact側でフォーム送信する場合に、CSRFトークンを含める方法について調べてみたので説明します。

## 1. Laravelでcsrfトークンを生成する
<span>@</span>csrfディレクティブも含めて、CSRFトークンはLaravel側の機能なので、トークンの生成はLaravel側で行う必要があります。
csrfトークンの生成はLaravelの「csrf_token()」関数を用いて生成します。


## 2. HTMLのmetaタグにcsrfトークンを埋め込む
生成したトークンはReact側に渡す必要があります。
トークンを渡す方法は色々ありますが、今回はHTMLのmetaタグ内に埋め込む方法を用います。
```html
    <meta name="csrf-token" content="{{ csrf_token() }}">
```

## 3. React側でCSRFトークンを取得する
次に、2.でセットしたmetaタグのcsrfトークンをReactのコンポーネントで取得します。
以下は、TSXで記述した例です。
トークンの取得方法は様々ありますが、以下のサンプルではuseRefフックを用いています。
```tsx
const Form = () => {
    const metaCsrfToken = document.querySelector("meta[name='csrf-token']") as HTMLMetaElement;
    const csrfToken = useRef<string>(metaCsrfToken.content);
    ...
}

```

## 4. Formタグにcsrfトークンを含める
最後に、取得したcsrfトークンをformタグの中に含めます。
inputタグのtype属性を「hidden」、name属性の値を「_token」、value属性の値を「トークン」に設定することでcsrfトークンを含めることができます。
以上で、LaravelでReact側のForm送信が可能になります。
```tsx
const Form = () => {
    const metaCsrfToken = document.querySelector("meta[name='csrf-token']") as HTMLMetaElement;
    const csrfToken = useRef<string>(metaCsrfToken.content);
    return(
        <form action="/hoge" method="post">
            <input type="hidden" name="_token" value={ csrfToken.current } />
            ....
            <button type="submit">登録</button>
        </form>
    );
}

```

## まとめ
LaravelでReact側のForm送信を実装したい場合は、以下の手順で行います。

1. Laravel側でCSRFトークンを生成する
1. HTMLのmetaタグにcsrfトークンを埋め込む
1. React側でCSRFトークンを取得
1. Form送信時にトークンを含める


---
参考サイト
　- [LaravelのフォームをReactで使う際にcsrfトークンを含める方法](https://www.engilaboo.com/laravel-react-csrf/)
　- [Laravel】CSRF対策 「@csrf」や「 {{ csrf_field() }} 」が意味するもの](https://qiita.com/messhii222/items/972f12033edf548e8eda)