OmniAICreator/Qiita-1.07M huggingface dataset:
TerraformでVPC Origin作成時にVPC Origin用のセキュリティグループIDをインバウンドルールに紐付ける。

# はじめに
TerraformでCloudFrontのVPC Originを作成する際に、一度のapplyでELBのセキュリティグループのインバウンドルールにVPC Origin用のセキュリティグループIDをソースとして指定したルールを作成することができたため、紹介したいと思います。

# VPC Origin作成時の問題について
CloudFrontのVPC Originを作成すると、CloudFrontから直接プライベートのInternal ELBやEC2に接続するためのENIとENIに紐付くセキュリティグループが自動で作成されます。

CloudFrontから内部のELBやEC2にアクセスする際にはENIを通ってアクセスすることになるため、ENIに紐付くセキュリティグループのIDをELBやEC2のセキュリティグループのインバウンドルールにソース指定することで、CloudFrontからのアクセスに限定することができます。

![vpc_origin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/b35e67b4-73a9-ee5c-890a-6b6520329dee.png)

そのため、TerraformでVPC Originを作成する際に、ELBやEC2のセキュリティグループのインバウンドルールもまとめて更新したいところですが、ENIとENIに紐付くセキュリティグループはVPC Originを作成した際に同時に作られるため、予め指定することはできないことから、VPC Origin作成後に、作成されたVPC Origin用セキュリティグループを指定して再度applyする必要があります。

また、VPC Originで作成されるENIはCloudFront用の特殊なENIのため、TerraformやCLIで事前に作成しておくことはできません。

# VPC Originとセキュリティグループのインバウンドルールへの紐付けを一度に行う
VPC Origin作成時に同時に作成されるセキュリティグループ名は固定で`CloudFront-VPCOrigins-Service-SG`と決められているので、VPC Originリソース作成後に`CloudFront-VPCOrigins-Service-SG`のセキュリティグループIDを検索した後、ELBやEC2のインバウンドセキュリティグループルールに紐付ける処理が動くようにすれば問題ありません。

そのため以下のように`depends_on`で作成順を制御することで一度にインバウンドセキュリティグループルールへの紐付けまで行なうことができます。

以下、VPC OriginとELB用セキュリティグループを作成するterraformの抜粋。
※ELBの作成とVPCの作成リソースは除外しているので、実際に作成する際には設定してください。

```terraform:VPC Origin用セキュリティグループの紐付け
# VPC Originの作成
resource "aws_cloudfront_vpc_origin" "elb" {
  vpc_origin_endpoint_config {
    name                   = "Example VPC Origin"
    arn                    = aws_lb.elb.arn
    http_port              = 8080
    https_port             = 8443
    origin_protocol_policy = "https-only"

    origin_ssl_protocols {
      items    = ["TLSv1.2"]
      quantity = 1
    }
  }
}

# CloudFront-VPCOrigins-Service-SGのセキュリティグループIDの取得
data "aws_security_group" "vpc_origin_sg" {
  # VPC Origin作成時に作られるセキュリティグループIDを取得するため、depends_onでVPC Originのリソースを指定
  depends_on = [aws_cloudfront_vpc_origin.elb]
  filter {
    name   = "group-name"
    values = ["CloudFront-VPCOrigins-Service-SG"]
  }
}

# ELB用セキュリティグループ
resource "aws_security_group" "elb" {
  name        = "elb-security-group"
  description = "elb-security-group"
  vpc_id      = aws_vpc.main.id
  tags = {
    Name = "elb-security-group"
  }
}

# ELB用セキュリティグループインバウンドルール
resource "aws_vpc_security_group_ingress_rule" "elb" {
  # VPC OriginのセキュリティグループID取得後にインバウンドルールに紐付けるため、depends_onでVPC Originのセキュリティグループのデータリソースを指定
  depends_on = [data.aws_security_group.vpc_origin_sg]

  security_group_id            = aws_security_group.elb.id
  ip_protocol                  = "tcp"
  from_port                    = 80
  to_port                      = 80
  referenced_security_group_id = data.aws_security_group.vpc_origin_sg.id
}
```

terraform apply実行後のELB用セキュリティグループ。

ELB用セキュリティグループのインバウンドルールのソースにVPC Origin用のセキュリティグループ（`CloudFront-VPCOrigins-Service-SG`）が付与されました。

![Monosnap_20250126_193352.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/c28c12c2-e9c9-efb1-c0ae-4b539ee416d7.png)

# おわりに
書いてしまえば`depends_on`を指定するだけの話ですが、方法を思いつくのに時間がかかったため、記事に残しておこうと思います。
アジャイル開発：ハイブリッド開発

# はじめに
開発手法を学んでいるときに、ウォーターフォールとアジャイル開発を組み合わせた
**ハイブリッド開発**について目にしたので学んだ結果を記事にまとめてみる。

# アジャイル開発のハイブリッド開発とは
ハイブリッド開発とは、従来のウォーターフォール開発とアジャイル開発の良いところを組み合わせた開発手法です。
この手法は、両方の開発方法のメリットを活かしつつ、デメリットを補完することを目的としています。

## ハイブリッド開発の特徴
1. 柔軟性と計画性の両立 ハイブリッド開発では、プロジェクトの初期段階でウォーターフォール的なアプローチを取り、全体の方向性や大枠を決定します。
これにより、プロジェクトの見通しが立てやすくなります。
その後、詳細設計やコーディングの段階でアジャイル的なアプローチを採用し、柔軟に対応できるようにします。 
2. 工程別の使い分け プロジェクトの各段階に応じて、ウォーターフォールとアジャイルを使い分けます。
例えば、要件定義から基本設計をウォーターフォールで行い、詳細設計・コーディング・単体テストをアジャイルで実行し、最後の総合テストをウォーターフォールで行うといった具合です。

## ハイブリッド開発のメリット
1. フィードバックの迅速な反映 アジャイルの特性を活かし、小さなサイクルで開発を進めることで、クライアントからのフィードバックを迅速に反映できます。
2. 修正や手戻りへの柔軟な対応 開発の中盤でアジャイル手法を採用することで、修正や手戻りが発生しても早い段階で対応が可能になります。
3. 開発方針の一貫性 プロジェクト初期にウォーターフォール的なアプローチで方向性を固めることで、開発方針がブレにくくなります。

## 注意点
1. ウォーターフォールとアジャイルの境界線の設定 プロジェクトの特性に応じて、どの段階でどちらの手法を採用するかを慎重に決める必要があります。
2. チームサイズの考慮 アジャイル部分では議論ベースで進むため、大人数のチームでは意思決定に時間がかかる可能性があります。

# ハイブリッド開発の具体的な工程について
## 1. 上流工程（ウォーターフォール開発）
・要件定義
　クライアントのニーズを明確化し、開発すべき機能や性能を詳細にドキュメント化します。
・基本設計
　要件定義に基づき、システムの全体像を設計します。必要なハードウェアやミドルウェアの選定も行います

## 2. 中流工程（アジャイル開発）
・詳細設計
　機能ごとに詳細設計書を作成します。これは開発者向けのドキュメントとなります
・実装
　詳細設計書に基づいて、機能ごとに実装を行います
・レビュー
　実装した機能を実際に動作させ、クライアントや関係者からフィードバックを得ます
・単体テスト
　実装した機能が正常に動作するかテストします。エラーが発生した場合は修正を行います

この中流工程では、スプリントと呼ばれる短い期間で開発を繰り返し、定期的にスプリントレビューを行います。

## 3. 下流工程（ウォーターフォール開発）
・結合テスト
　個々の機能を統合し、システム全体としての動作を確認します
・システムテスト
　システム全体の品質を検証し、リリースに向けた最終確認を行います

このように、ハイブリッド開発では上流と下流でウォーターフォール的なアプローチを取りつつ、中流工程でアジャイル的な反復開発を行うことで、計画性と柔軟性を両立させることが可能となる。

## アジャイル開発の中流工程のメリット
1. 後戻りの工数を抑えやすい 小さな単位で計画から設計、実装、テストを繰り返すため、問題が発生しても1つのイテレーション内での修正で済むことが多く、大規模な手戻りを避けられます。
2. 仕様変更に強い 開発途中でクライアントやユーザーとコミュニケーションを取りながらフィードバックを行い、確認しながら進められるため、仕様変更や追加に柔軟に対応できます。
3. 開発スピードが速い 小単位で各機能を切り分けて開発し、優先度が高い順にテスト・リリースを行うため、開発期間が短縮されます。
4. ユーザビリティの向上 開発工程で何度もリリースとテストが行われ、クライアントやテストユーザーからの意見を取り入れるため、ユーザビリティの高いソフトウェアの完成が期待できます。
5. チームワークの向上 少人数の開発チームが毎日ミーティングを行い、進捗状況やトラブルについて報告し合うことで、チームワークが向上します。
6. 顧客ニーズへの迅速な対応 各イテレーションで顧客要望とのすり合わせが行われ、改善点が見つかれば次回のイテレーションで反映されるため、顧客のニーズに応じやすくなります。


以上
Nuxt.js ルーティング学習メモ

# 1. どうやってルーティングを設定するか
nuxt_study/pages/index.vueをコピーして、
nuxt_study/pages/tests/test.vueを作成する。

http://localhost:3000/tests/test
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497869/f946f486-c179-734a-3630-078e3490b7af.png)

仕組みとしては、nuxt_study/pagesの下にファイルを作ればルーティングが自動設定される。
nuxt_study/.nuxt/router.js
※ ここは多分触らなくていい。

# 2. 動的ルーティング
nuxt_study/pages/index.vueをコピーして、
nuxt_study/pages/tests/_id.vueを作成する。


_id.vueのように最初にアンダースコアをつける。
適当な箇所に以下を記載して、URLの値が取れるかチェック。
http://localhost:3000/tests/aaaaaaaaaaaaaaaaaaaaaa
```nuxt_study/pages/tests/_id.vue
{{ this.$route.params.id }}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497869/623b7775-461c-baf1-91c5-2e23bf844ee6.png)

「aaaaaaaaaaaaaaaaaaaaaa」が画面に表示されているのでOK。

バリデーションも設定してみたい所感

# 3. 参考
ありがとうございました。
https://qiita.com/futy_0123/items/a3180650f423fc3f2d36
FirestickTV スリープ解除忘備録

スマートTV化のためのスリープ解除設定。毎回忘れがちなのでメモ
## FirestickTVで開発者オプションを表示させる
 1.設定-「My FireTV」から「バージョン情報」を選択。
 2.選択ボタンを連打
 3.開発者オプションが現れるので選択
 4.ADBデバッグをオンにする
 
## ADB(SDK Platform-Tools)で設定
1.ダウンロードし解凍
　https://developer.android.com/tools/releases/platform-tools?hl=ja
2.CMD起動して、platform-toolsに移動
```
#最初にきっとく
adb kill-server
#開始
adb start-server
```
 その後こんなのが出るので、許可
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2858450/a5b6fafc-cfa2-60f2-7269-9230a21f372d.png)
```
#FireTVに接続（FireTvのIPをしらべておく）
adb connect 192.168.1.7　
#FireStickTVでUSBデバッグを許可しますか？と出るので許可
#failedだったら再度接続
#接続確認
adb devices
#スリープまでの時間を確認
adb shell settings get secure sleep_timeout
#スクリーンオフまでの時間を確認（2147460000になっていた）
adb shell settings get system screen_off_timeout
#スリープ0に設定
adb shell settings put secure sleep_timeout 0
#設定できたらDisconnect
adb disconnect 192.168.1.7
#終了
adb kill-server
pandas マルチインデックスの動き


Index Levels
outside = ['G1','G1','G1','G2','G2','G2']
inside = [1,2,3,1,2,3]
hier_index = list(zip(outside,inside))
hier_index = pd.MultiIndex.from_tuples(hier_index)

df = pd.DataFrame(np.random.randn(6,2),index=hier_index,columns=['A','B'])

上記のように設定したマルチラベルにおいて値を抽出するとき
上は動くのに下は動かない理由が分からない。
df.loc['G1'].loc[1]['B']
df.loc['G1'][1]['B']

#チャッピー回答メモ

結論
df.loc['G1'].loc[1]['B'] が動作する一方で df.loc['G1'][1]['B'] が動かないのは、pandas におけるデータ型の違いとアクセス方法の解釈によるものです。

df.loc['G1'].loc[1]['B'] の動作
df.loc['G1']:

'G1' に対応する行を取得します。

この結果は以下のようなサブデータフレーム（DataFrame）になります：

  　　　A　　　　　B
1 　 0.153661 　 0.167638
2 　-0.765930 　 0.962299
3 　 0.902826 　-0.537909

.loc[1]:

サブデータフレームから行ラベル 1 を持つ行を取得します。

この結果は1行だけの Series になります：
A    0.153661
B    0.167638
Name: 1, dtype: float64
['B']:

Series からインデックス 'B' に対応する値を取得します。
この一連の操作が正常に動作し、'B' に対応する値が返されます。

df.loc['G1'][1]['B'] のエラー
df.loc['G1']:

'G1' に対応するサブデータフレームを取得します（上記と同様）。
[1]:

ここでの [1] は、サブデータフレームに対する操作として解釈されます。
**サブデータフレームに対する角括弧 [] のデフォルトの挙動は「列ラベル」として解釈される」**ため、ここでは列ラベル 1 を探します。
しかし、サブデータフレームの列ラベルは ['A', 'B'] であり、1 という列ラベルは存在しないため、KeyError が発生します。
解決方法
以下のように記述することでエラーを回避できます：

.loc を使用: 行ラベルを明示的に指定するには .loc を使用します。
df.loc['G1'].loc[1]['B']  # 正しく動作
.iloc を使用: インデックス番号（ゼロ始まり）でアクセスする場合は .iloc を使用します。
df.loc['G1'].iloc[0]['B']  # サブデータフレームの最初の行の列 'B' を取得

注意点
角括弧 [] の挙動に注意:

サブデータフレーム（DataFrame）に対する [] はデフォルトで「列ラベル」として解釈されます。
一方、Series に対する [] は「インデックスキー」として解釈されます。
一貫して .loc または .iloc を使う:

.loc は行ラベルや列ラベルに基づいたアクセスをサポートします。
.iloc は行番号や列番号による位置ベースのアクセスをサポートします。
引き継ぎ作業を怠る人間へ

# はじめに
担当者が入れ替わるタイミングで発生する追加作業が**引き継ぎ作業**である。
この引き継ぎ作業という代物は、本当に人の性格が滲み出るものだと思う。

過去に何度も引き継ぎ元から引き継ぎを行ったことがあるが、皆口を揃えてこう言う。
「ここにある資料が全てです」
「何か質問があったら質問して下さい」

ただし、私の経験上例外無くこの手のパターンは、``不備がある``。
もう間違いなく、100%。
そしてこう言われた引き継ぎ先の担当者は必ず困ることになる、間違いなく120%。

今まさに引き継ぎ先として引き継ぎ作業を行っているが絶賛困り果てているので、、この記事を書いていく。
以下３点について記載していく。
・そもそも何で引き継ぎ作業って発生するの？
・引き継ぎってどんなことが必要なの？
・何で皆引き継ぎ適当すぎるん？？？

# そもそも何で引き継ぎ作業って発生するの？
## 業務効率と生産性の維持

業務の担当者が変わる際、適切な引き継ぎがないと業務効率が大幅に低下します。
新しい担当者が業務の進め方を理解できず、上司や関係者に頻繁に質問することで、結果的に生産性が低下してしまいます。
つまり、**引き継がれたはずの担当者がシンプルに困ります。**

## 企業の信頼性の確保

引き継ぎは単なる社内の問題ではなく、取引先や顧客との関係にも大きな影響を与えます。
不十分な引き継ぎは、顧客からの問い合わせに適切に対応できないリスクがあり、企業の信頼を損なう可能性があります。

## 前任者と後任者の負担軽減

適切な引き継ぎは、前任者が新しい業務に集中できる環境を作り、同時に後任者の早期戦力化を支援します。
不十分な引き継ぎは、前任者に頻繁な問い合わせを強いることになり、両者にとって非効率的です。

結論として、引き継ぎは組織の持続的な成長と効率的な業務運営に不可欠なプロセスとなります。

# 引き継ぎってどんなことが必要なの？
詳細に書くといっぱいになるので、引き継ぎに必要な事柄は別記事にまとめる。
立場や役割によって内容は異なるが、箇条書きで必要そうな引き継ぎ項目を記載する。
・部門の戦略と方針
・組織構造と人材管理
・プロジェクト管理
・予算と財務
・技術インフラとツール
・デプロイメントとリリース
・連絡手段
・ステークホルダー管理
・知識管理とナレッジベース
・保守・運用面　
　etc...　and more!!!

パッと思いつくことを記載したが、思いつきで書いてもいっぱい出てくる。

また、既存の資料がしっかりしているからそれ見せるだけで良いよね、もありえないから皆様ご注意を。
既存の資料はいわゆる分かっている人向けの資料であることが多い。
また、資料の中身の背景にある目的や意図が欠けていることがあるから、それらを補足してもらう必要がある。

そもそも、体系立てて理解しやすい順番に整理してもらわないと、引き継ぎ先の担当者はどこから資料を見れば良いのかめちゃくちゃ迷う。
つまり、引き継ぎがスムーズに行われるように、大なり小なり引き継ぎ資料は必要となる。

そのため、
<font color="red">**間違っても既存の資料があるからそれを見せれば大丈夫、とは絶対にならないはずだ。**</font>


# 何で皆引き継ぎ適当すぎるん？？？
引き継ぎが必要な理由はそりゃ当たり前だよね、と言うことしか上記は記載していない。
では、何で引き継ぎを適当にするのか？

## モチベーションの低下
退職や異動が決まった後は、現在の業務へのモチベーションが低下しがちです。
特に退職の場合、会社への帰属意識が薄れ、丁寧な引き継ぎを行う意欲が失われることがあります

↑正直、これが90%理由に該当すると思います。
モチベーションが低下しているかどうかは、口頭で説明を受けていると本人の態度でハッキリ分かる。
この辺り引き継ぎ元の本人はバレていないと思っているかもしれないが、そんなのは透けて見えるものだ。

タチが悪いのは、引き継ぎをやっているつもりの担当者。
引き継ぎが適当なことに全く気づいてさえいない担当者もいるのだから、タチが悪い。。
まあ、不備があることに気がつきながら引き継ぎを適当に行う担当者も大概だが。。

↓残りの10%の理由は以下に続きます。

## 時間的制約
多くの場合、引き継ぎは人事異動や退職の直前に行われるため、十分な時間が確保できないことがあります。
特に急な人事異動や退職の場合、引き継ぎの準備時間が不足し、結果として適当な引き継ぎになってしまう可能性があります。

## 業務の複雑さ
長年担当してきた業務は、担当者にとっては当たり前になっているため、どの程度詳細に説明すべきか判断が難しくなります。
このため、重要な情報が抜け落ちたり、説明が不十分になったりすることがあります。

## 引き継ぎスキルの不足
適切な引き継ぎを行うためには、コミュニケーション力や文書作成能力が必要です。
これらのスキルが不足している場合、効果的な引き継ぎを行うことが困難になります。

## 引き継ぎの重要性の認識不足
引き継ぎの重要性を十分に理解していない場合、その準備や実施を軽視してしまう傾向があります。
自分の評価や将来の仕事にも影響する可能性があることを認識していないことが、適当な引き継ぎにつながっています。

# まとめ
引き継ぎ先の気持ちになって、みんな引き継ぎ作業を行ってね、ということです。
マジで「立つ鳥跡を濁さず」と言うことですね。

また、認識が低い人が本当に多いのですが、引き継ぎと言う作業も必要な職務の一つです。
手を抜いて良い部類の作業ではありません。

引き継ぎ作業の重要性について理解した上で、
引き継ぎと言う一つのスキルを使って引き継ぎ先が極力困らないように引き継ぎを行うようにしましょうーーーーー

※ちなみにIT業界は意外と狭いから、長く続けていればいつかまた会うことになるよね、
　といつもベテランエンジニアから言われていたが、意外と再会はしない。
 　そんなことは置いておいて、落ち度があることが分かっていて何も引き継ぎをしないと言うのは、ただの職務怠慢であり、サボりだよね。と言うことを強く言いたい。

以上
ログイン後のルートページを変える (deviseを使用)

# Why?
ログイン前とログイン後でルートページを変えたいな～と思って調べてみました。
さっくりとした備忘録です。

# やり方
[deviseの公式](https://github.com/heartcombo/devise?tab=readme-ov-file#controller-filters-and-helpers)の方で
>ユーザのサインイン、アカウントの確認、パスワードの更新の後、Deviseはリダイレクト先のスコープ付きルートパスを探します。 例えば、 :userリソースを使用する場合、user_root_pathが存在すればそれが使用され、そうでなければデフォルトのroot_pathが使用されます。


と書かれていたので、rootを指定したらうまく動いてくれた。
コードはChatGPTに助けてもらったので爪甘なところあったらコメント頂けると幸いです。

ログイン前は`"static_pages#start"`をルートとして
ログイン後は`"cards#index"`をルートにする場合。

```config/routes.rb
Rails.application.routes.draw do
  #ログイン後のルートページ
  authenticated :user do
    root to: "cards#index", as: :user_root
  end
  
  # ログイン前のルートページ
  unauthenticated do
    root to: "static_pages#start"
  end
  
  devise_for :users
  resources :cards, only: %i[index]
  mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
end
```
この時にログイン後のルートページをログイン前のルートページよりも前に書いておかないとログイン前の方のルートが適応されてしまうらしいので注意。

おしまい。
個人開発を加速させるテストの考え方と実装例（🔰）

## はじめに
現在個人プロダクト開発を行っており、そのテストを実施するにあたり、自分用にその必要性などを整理してみました。Ruby on Railsを使ったアプリケーションのテスト向けです。

## なぜ必要か
### バグを早期に見つける
開発を進めると、コードがどんどん蓄積され、場合によってはバグに依存したコードが出てきます。これらのバグをあとから修正しようとすると、そこに依存する大量のコードを修正しなければならず、コストがかかってしまいます。

そのため、バグを初期段階でみつけることは、コスト削減となり大きな利益になって返ってきます。また、バグの発見と修正は、それが作られた時間に近ければ近いほど簡単です。

### 仕様書となる
テストは唯一信頼できる設計の仕様書となります。
私はよく「このコードってどう動いてたっけ？」と忘れてしまうことがあるため、将来の自分が記憶を失ったつもりで、テストを実装しておくよう心がけたいと思います。

### 設計の欠陥を明らかにする
一つのテストを実装するに苦痛が伴うのであれば、そのコードは改善の余地があると疑いの目が必要です。例えば、コンテキストを要求しすぎている、他のオブジェクトとの依存関係を持ち過ぎている、等々の原因が考えられます。

こういった実装は、他のオブジェクトから見ても再利用が難しいので設計の欠陥があると慎重になる必要があるそうです。設計に疑いの目をむけるきっかけを提供するのもテストが必要の理由です。


## 実装例
### describe / context / it の説明を明確に書く
describe にはテスト対象の「クラス」や「メソッド」などを書きます。
context にはテストしようとしている状況「ログイン中のユーザーの場合」などを書きます。
it は期待する結果を書きます。このとき「正しいこと」などのような表現を避けます。「正しいとはどういう状況か」を書きます。

describe / context / it の説明を読むことでテストの概要がわかるのが理想的です。
なんのテストをしているかわかりやすく説明しましょう。

### AAA（ Arrange-Act-Assert）
テストコードを Arrange（準備）、Act（実行）、Assert（確認）の3つのフェーズに分けて記述する、テストコードを読みやすくするためのパターンのひとつです。それぞれのフェーズで記述する内容は次のようになります。

`Arrange`
テストを実施するために必要となる前提条件や必要なデータを準備する。
テスト環境の初期化や依存関係（テストダブルも含む）の構築。
テスト対象のメソッドに渡すパラメータ。
`Act`
テスト対象の振る舞いを実行する。
テスト対象のメソッドの実行など。
`Assert`
期待された結果であるかを確認する。

### 実装
上記２点を考慮した以下のテストコードの例を示します。今回は、Calculator クラスを作成し、その #add メソッドが正しく動作するかをテストします。以下の記事を参考にしました。



```ruby calculator.rb
class Calculator
  def add(a, b)
    a + b
  end
end
```

テストコード例
```ruby calculator_spec.rb
require 'rails_helper'

RSpec.describe Calculator, type: :model do
  describe '#add' do
    let(:calculator) { Calculator.new } # Arrange: テストに使うオブジェクトを準備

    context '2つの正の数を足す場合' do
      it '正しい合計を返す' do
        # Act: メソッドを呼び出す
        result = calculator.add(3, 5)
        
        # Assert: 結果を検証
        expect(result).to eq(8)
      end
    end
  end
end
```

テストコマンド実行
```bash
rspec spec/models/calculator_spec.rb
```

### モデルとコントローラー
これは、自分用のメモですが、テストを行う際には、モデルとコントローラーが果たす役割を理解することが大切です。それぞれの役割、テスト対象を簡単にまとめました。特に、自分はコントローラーの実装が多くなってしまうため、以下の役割を意識した実装を心がける必要があります。

| **項目**       | **モデル**                                     | **コントローラー**                              |
|----------------|-----------------------------------------------|-----------------------------------------------|
| **役割**       | データの管理、バリデーション、ビジネスロジック | リクエストの処理、レスポンスの作成             |
| **テスト対象** | バリデーション、メソッド、データ操作           | HTTPステータスコード、レスポンス、ビューの呼び出し |
| **依存範囲**   | データベースや関連モデル                      | モデル、ビュー、リクエスト                     |
| **例**         | ユーザー名のバリデーションやフルネーム計算     | ユーザー一覧の取得や表示、APIレスポンス生成     |
| **テストの目的**| データやロジックが正しいかを確認する           | リクエスト処理が正しく行われるかを確認する     |


## さいごに
テストの記述、実行はコストがかかるため、テストファーストのプログラミングは面倒だと思っておりました。しかし、テストのコストがかかることの解決は上手くなるのみです。テストを書くスキルを磨くことで、全体を俯瞰したときにその価値が見えてきます。
まだまだ、個人開発の先は長いですが、費用対効果の高いテストを実装するよう心がけたいです！
【Next.js】 レンダリング時にアニメーションがリセットされるものとされないものがある

## はじめに

Next.jsでサイト制作中に、ページが再レンダリングするとき、アニメーションがリセットされるものとされないものの２種類あることに気づきました。本記事では、以下について詳しく解説します。

- **CSS アニメーションがリセットされない理由**
- **JavaScript アニメーションがリセットされる理由**
- **解決策としてのアニメーションのコンポーネント化**

最後に簡単なコード例を通して、実際の実装方法をお伝えします。


## アニメーションがリセットされるものとされないものの違い

### 1. CSS アニメーションはリセットされない

CSS のアニメーションは、ブラウザのレンダリングエンジンで再生されています。そのため、React や Next.js のコンポーネントの再レンダリングやページ遷移の影響を受けません。


### 2. JavaScript アニメーションはリセットされる

JavaScript アニメーションは、レンダリングの影響を直接受けます。レンダリング時に状態がリセットされ、アニメーションが最初からやり直しになることがあります。

再レンダリングで React が古い DOM 要素を削除し、新しい要素を作成した場合、古い要素に紐づいていたJSアニメーションの状態はすべて失われます。

またReact の useEffect や useState は、コンポーネントが再レンダリングされると再実行されるため、JSアニメーションの進行状況がリセットされます。

#### 例:

```tsx
import { useState, useEffect } from "react";
import JSAnimatedBox from "./JSAnimatedBox";
import CSSAnimatedBox from "./CSSAnimatedBox";

const Page = () => {
  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      setScrollPosition(window.scrollY); // スクロール位置を状態で管理
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  return (
    <div>
      <h1>スクロールアニメーション</h1>
      <p>現在のスクロール位置: {scrollPosition}</p>
      {/* CSS アニメーション部分 */}
      <CSSAnimatedBox />
      {/* JavaScript アニメーション部分 */}
      <JSAnimatedBox />
    </div>
  );
};

export default ScrollAnimation;
```

この場合、コンポーネントが再レンダリングされるとCSSAnimatedBoxコンポーネントは最後までアニメーションが実行され、JSAnimatedBoxのアニメーションは初期化されます。

---

## 解決策: アニメーション部分のコンポーネント化

JavaScript アニメーションがリセットされるのを防ぐために、ページ全体がレンダリングされてる要因のコードをコンポーネント化して影響範囲をコンポーネント内に留めておく必要があります

#### 修正版: コンポーネント化されたアニメーション

```tsx
import ScrollWatcher from "./ScrollWatcher";
import JSAnimatedBox from "./JSAnimatedBox";
import CSSAnimatedBox from "./CSSAnimatedBox";

const ScrollAnimation = () => {
  return (
    <div>
      <h1>スクロールアニメーション</h1>
      {/* スクロール監視部分 */}
      <ScrollWatcher />
      {/* CSS アニメーション部分 */}
      <CSSAnimatedBox />
      {/* JavaScript アニメーション部分 */}
      <JSAnimatedBox />
    </div>
  );
};

export default ScrollAnimation;
```




## 結論

- **CSS アニメーション**はブラウザのレンダリングエンジンが制御しているため、リセットされることはありません。
- **JavaScript アニメーション**はレンダリングに依存するため、再レンダリング時にリセットされます。
- レンダリング影響範囲内にjsアニメーション置かないように適宜コンポーネント化する
今こそ知るべき！ICP（Internet Computer）とは？開発者が注目すべき理由

## イントロダクション

近年、ブロックチェーン技術の進化が加速する中で、「分散型インターネット」を実現するための新たな取り組みが注目を集めています。その代表例が **Internet Computer（ICP）** です。本記事では、ICPの魅力と、なぜ今開発者が注目すべきなのかを解説します。

---

## 1. ICPとは？

ICP（Internet Computer）は、Dfinity財団が開発したブロックチェーンベースの分散型クラウドプラットフォームです。従来のブロックチェーンとは異なり、ICPは以下のような特長を持ち、**従来のWeb2とWeb3のギャップを埋める** 画期的なプロジェクトです。

### ICPの特徴

1. **スマートコントラクトの拡張「Canister」**  
   - 従来のブロックチェーンのスマートコントラクトとは異なり、より高度な計算とストレージが可能。
2. **ガス代不要のシステム**  
   - ユーザーが手数料を気にせず、スムーズに利用できる。
3. **フルスタックのWebアプリ構築が可能**  
   - サーバーレスでフロントエンドとバックエンドを統合。

---

## 2. 開発者がICPを選ぶべき3つの理由

### 1. フルスタックdAppを構築できる環境

ICPを使えば、従来のWeb2のような開発体験を維持しながら、**完全に分散化されたアプリケーション（dApp）** を構築できます。例えば、以下のような構成が可能です：

- **フロントエンド:** React, Vue.js  
- **バックエンド:** ICPのCanister（Motoko / Rust / TypeScript対応）  
- **データ管理:** 分散型ストレージ（従来のDB不要）  

### 2. 他のブロックチェーンと比べた優位性

| 比較項目 | ICP | Ethereum | Solana |
|---|---|---|---|
| 手数料 | ほぼ無料 | 高額 | 中程度 |
| 処理速度 | 2秒以下 | 15秒以上 | 数秒 |
| データ保存 | 直接ブロックチェーン上に保存 | 外部ストレージ依存 | 一部依存 |

ICPは、**手数料ゼロ・高速処理・スムーズなデータ管理** を兼ね備えた、他のブロックチェーンと比べても圧倒的に使いやすい開発環境です。

### 3. すぐに開発を始められるシンプルなツールチェーン

ICPの開発には、以下のようなシンプルな手順で始められます：

```bash
npm install -g dfx
dfx new my_project
```

```motoko
actor {
  public query func greet() : async Text {
    return "Hello, ICP!";
  }
}
```

```bash
dfx start
dfx deploy
```

---

## 3. ICPのユースケース事例

ICPの強みを活かした実際の事例を紹介します。

1. **Distrikt（分散型SNS）**  
   - 中央集権的なSNSとは異なり、ユーザーのデータを完全管理。
2. **Fleek（Web3ホスティング）**  
   - Webサイトを分散型ストレージにデプロイできるソリューション。
3. **OpenChat（分散型メッセージング）**  
   - 完全にオンチェーンで動作するプライベートチャットアプリ。

これらのプロジェクトは、ICPの分散型クラウドとしての可能性を証明しています。
前のディレクトリに移動する！cdhコマンド

:::note info
この記事は、[fishファンクションシリーズ](https://qiita.com/kokecoco/items/4857bf3abaaf85ab51e7)の2記事目です。わたしが勝手になっていることなのでお気になさらず。他のファンクションも見てみてください。
:::

こんにちは。KITsのプログラマーの苔コッコーです。
今回は、もっとも便利だと感じているcdhコマンドを紹介していこうと思います。
コードは一番下に貼っておきます。fishです。

# 紹介
このコマンドは、現在のセッションでそこまでに移動したディレクトリからfzfで選択し、そこへ移動できるコマンドです。複数のディレクトリをまたいで開発する際にとても便利です。

使用例です。
![使用例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723455/40c5dc3f-49c0-3fc1-9716-e9ad3310b345.gif)

環境数が増えてくると結構便利です。
cdコマンドの実行時に環境変数に記録し、cdhの実行時にそれを読み出すようにしています。

# コード
```fish
function cd
  set OLDPWD_TEMP $PWD
    if test (count $argv) -eq 0
        # 引数なしで呼ばれた場合、ホームディレクトリに移動
        builtin cd ~
    else if test "$argv[1]" = '-'
              # 'cd -' の処理 ($OLDPWD に移動)
        if test -n "$OLDPWD"
            builtin cd $OLDPWD
        end
    else
        # その他の引数がある場合は通常のcdを実行
        builtin cd $argv
    end

    set OLDPWD $OLDPWD_TEMP
    # ディレクトリ移動後、現在のディレクトリを履歴スタックに保存
    set -g DIR_STACK $PWD $DIR_STACK
end

function cdh
    # fzfでディレクトリ履歴から選択
    set dir (printf "%s\n" $DIR_STACK | fzf)
    if test -n "$dir"
        builtin cd $dir
    end
end
```
【24H2】Windows 11 を更新して以降 WSL ファイルシステムをエクスプローラから開けなくなった

誘惑に負けて Windwos を不具合が続々と報告されている 24H2 に更新したところ，しっかりと嵌ったのでその記録です．

# 症状

- WSL 領域のディレクトリを指すクイックアクセスのピン留めが壊れる ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089746/60b02efe-e40f-91fa-a479-02d6aca97217.png)

- 壊れたピン留めを解除できない (「クイックアクセスからピン留めを外す」が表示されない)

# 処置

## WSL 領域にアクセスする
アドレスバーに `\\wsl$` と手打ちすると，お馴染みの画面に遷移します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089746/58406dce-0ae5-f863-d709-efa692ba1266.png)

## WSL 領域のディレクトリをピン留めする
コンテキストメニュー >> 「ネットワークドライブの割り当て」 からお望みのディストリビューションを適当なネットワークドライブとしてマップしてください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1089746/71596283-c36f-5d0d-9db2-b29b9b01087e.png)


そのドライブのディレクトリとしてアクセスすると通常通りピン留めなどの操作ができます．


## 壊れたピン留めを消す

:::note warn
クイックアクセスの状態が初期化されます．
ピン留めの一覧は必要に応じて予めメモしておくなどしてください．
:::

アドレスバー手打ちで `%AppData%\Microsoft\Windows\Recent\AutomaticDestinations` にアクセスし，`f01b4d95cf55d32a.automaticDestinations-ms` を削除します．(他の適当な場所への移動がより安全かもしれません．)

# 終わりに
更新早々にこれ，通過儀礼でしょうか．

やはり 24H2 はもう少し待った方がいいかもしれません．

新しいタスクマネージャのデザインは気に入っています．グラフが半透明できれい．
タスクバーからタスクを終了できるのも嬉しいです．

# 参考文献

https://github.com/microsoft/WSL/issues/12173

https://github.com/microsoft/WSL/issues/12444
SSL通信の原理：対称鍵・非対称鍵を理解してみた

## はじめに
httpsを理解する時、httpにSSLを加えて通信経路での第三者による情報の盗聴や改ざんのリスクを防止できるということがわかったが、裏側がわからなくて結局SSLってなんでセキュアなのか肌で感じることができなかった。

SSLが動作する原理を理解するため、今回はSSLが動く対称鍵方式と非対称鍵方式についてしらべてみた。

## 非対称鍵方式
### ①キーペアの生成
PCで`PCのPublic key` + `PCのPrivate Key`を生成  
サーバーで`サーバーのPublic key` + `サーバーのPrivate Key`を生成

ここで、Public keyは暗号化だけに使われて、Private keyは復元にだけ使われる

### ②キー交換
お互いのPublic keyを送り合う

#### PCが持っている鍵
`PCのPublic key` + `PCのPrivate Key` + `サーバーのPublic Key(交換で獲得)`

#### サーバーが持っている鍵
`サーバーのPublic key` + `サーバーのPrivate Key` + `PCのPublic Key(交換で獲得)`

### ③流れ

``` mermaid
sequenceDiagram
    participant PC
    participant Server
    
    Note over PC,Server: >> PCからサーバーへの通信 >>
    PC->>Server: データを暗号化（サーバーのPublic Keyで）
    Server->>Server: 復号（サーバーのPrivate Keyで）
    
    Note over PC,Server: << サーバーからPCへの通信 <<
    Server->>PC: データを暗号化（PCのPublic Keyで）
    PC->>PC: 復号（PCのPrivate Keyで）
```

しかし、この非対称鍵方式が一般的に使われることはない

## 非対称鍵の何が問題？
キーペアを生成するために演算処理がかかりすぎる。しかも作ったものを長い間使い回しすることはできない（セキュリティのため）

例えば、コーヒーを飲むために使ったマグカップを毎回使い捨てているようなことをしている。

## 対称鍵方式
そのような非対称鍵方式のデメリットを回避するため、通信する前にキーペアを作ってディスクなどに保存しておく方法が生まれた。

### 効率
対称鍵が圧倒的にいい。先に作っておいてそもそもの計算量も少ないためCPUの使用量も少ないし、場合によってはもっとセキュアな面もある。

よく使われている対称鍵方式のAES-256と非対称鍵方式RSA 2048を比べてみると、RSAはbit数が大きいものの素因数分解のような仕組みをしているため今後量子コンピューターで容易に解読できる可能性がある反面、AES-256は単純な演算処理で構成されているが、量子コンピューターなどは得意としない演算になっているため解読しにくいらしい。

https://sslinsights.com/aes-encryption-vs-rsa-encryption/

### ①対称鍵の生成
PCで対称鍵を1つ生成する（サーバーで作るパターンもあるが、今回はPCで作る方を見ていく）
サーバーではキーペアを用意する（`サーバーのPublic Key` + `サーバーのPrivate Key`）

### ②キー交換
PCは`サーバーのPublic Key`を受け取る

#### PCが持っている鍵
`PCの対称鍵` + `サーバーのPublic Key(交換で獲得)`

#### サーバーが持っている鍵
`サーバーのPublic key` + `サーバーのPrivate Key` + `PCの対称鍵(③流れの一番上で受け取る予定)`

### ③流れ
``` mermaid
sequenceDiagram
    participant PC
    participant Server
    
    Note over PC,Server: >> 対称鍵を送る >> (サーバーで対称鍵を受け取る) 
    PC->>Server: 対称鍵を暗号化（サーバーのPublic Key）
    Server->>Server: 復号（サーバーのPrivate Key）
    
    Note over PC,Server: >> PCからサーバーへの通信 >>
    PC->>Server: データを暗号化（対称鍵）
    Server->>Server: 復号（対称鍵）
    
    Note over PC,Server: << サーバーからPCへの通信 <<
    Server->>PC: データを暗号化（対称鍵）
    PC->>PC: 復号（対称鍵）
```

## おわりに
結局もっと深いところまではわからなかったが、これだけでなぜSSLがいいのかは理解できた。
曖昧な知識をどんどん固めていきたいな〜
DBについて

# 1.概要
DBを使用したのでまとめます。

## 2.DB(datebase)とは
データを管理、保存するための仕組みです。
例えば、都道府県を管理するデータベースがあるとします。
このベータベースには次のような情報が保存されています。
- 都道府県コード
- 都道府県名
- 県庁所在地
- 登録された日付
- 更新された日付

データベース内の「都道府県を管理する構造」をテーブルです。
また、テーブル内の「都道府県コード」「都道府県名」「県庁所在地」「登録された日付」「更新された日付」などの各項目の情報はカラムです。
各都道府県には、これらのカラムに対応する情報が保存されています。各都道府県のデータがレコードです。

北海道レコードの例

以下は、北海道のレコードの例です
- 都道府県コードカラム: 01
- 都道府県名カラム: 北海道
- 県庁所在地カラム: 札幌市
- 登録された日付カラム: 2000/01/01
- 更新された日付カラム: 2025/01/01

## 3.RDS(relational database servise)とは
RDS（リレーショナルデータベースサービス）はシステム内のデータベースを効率的に管理し、複数のテーブル間でデータを紐づけるための仕組みです。
その際に重要なのがキーです。今回は3つのキーについて説明します。

---
### 1.主キー(Primary Key)
主キーは、データを一意に識別するために使用されます。主キーは条件があります。
- 中身が入っていること(nullではない)
- 中身が一意であること(重複がない)

**ひとつのテーブルつき一個まで設定できます。**
主キーとしてよく使用されるカラム名がidです。例えば、users テーブルの場合

| id |  name  |        mail        |
|----|--------|--------------------|
| 1  | tarou  | tarou@example.exe  |
| 2  | hanako | hanako@example.exe |

ここで、id が主キーとしてデータを一意に識別します。

---
### ２.外部キー(Foreign Key)
外部キーは、あるテーブルのカラムが別のテーブルの主キーを参照することによりテーブル間の関連性を構築する。これによりデータの整合性を取ることができる。

例:社員と部署のデータ
- 社員テーブルにある「部署カラム」は、部署テーブルを参照する
- 外部キーを設定することで、「部署コード」が部署テーブルに存在するものだけ登録可能になります

---
### 3.ユニークキー(Unique Key)
ユニークキーは、データの重複を許さないキーです。主キーと似ていますが違いは、nullを許容するかや複数設定可能な点です。

例:ログインに必要な情報など

- ログインにmailを入力する際に、複数あると正しいパスワードを判定できなくなるため　mailはユニークキーにする

---

## 3.安全な値をいれるために

デフォルトの状態だと様々な値を入力できます。しかし、想定していないデータが入力されてしまうとエラーの原因やシステムが重くなってしまう原因になります。これを未然に防ぐための対策を３つ説明します。

### 1. トランザクション (Transaction)

トランザクション とは、変更したいデータを一時的に保留し、すべての作業が完了した場合にのみ、実際のテーブルに反映させるデータベースの機能です。
これを使用することで、不完全なデータや不整合なデータが入力されることを防ぎます。

### 2.nullを許容しない

データベースでは、カラムに NULL (データが存在しない状態) を許容するかどうか設定できます。
NULL を許容しない設定にすることで、必ずデータが入力されているかをチェックし、空のデータが保存されることを防ぎます。

### バリデーション (Validation)

バリデーション は、入力されたデータの値を制限するバックエンド側の仕組みです。
例えば、文字数やデータ形式、範囲などを指定してチェックできます。これにより、想定外のデータが保存されることを防ぎます。

## まとめ
- データベースには、テーブル、カラム、レコードがあります
- RDSにはキーがあり、キーを使うことによりデータベースの整合性を取ることができます
- 不正なデータを防ぐ仕組みがあります。
Tableauで関連値フィルターを使う時の注意

仕事上、関連値フィルターを使うことがよくあるので、
その中でハマった点について共有します。

### 関連値フィルターとは
Tableauの関連値フィルターとは、
他にもフィルタがある場合に、他のフィルターがすべてかかった状態の、
そのフィルターの値を出すことです。
たとえばサンプルスーパーストアで「カテゴリ」と「サブカテゴリ」がフィルターに入っており、
「サブカテゴリ」のフィルターが「関連値のみ」に設定されていたら、
「カテゴリ」が「家具」に絞られると、
 - テーブル
 - 椅子
 - 家具
 - 本棚
 の値しかフィルターに表示されません。
 これが関連値フィルターです。

### 私がハマった関連値フィルターの事例
#### データの紹介
事例を紹介するにあたり、サンプルデータを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/57e556e3-033f-4f77-e6d3-4e427e3e3ed0.png)

主キーは「年月」「社員名」で、年月ごとの社員売上データだと考えてください。
ポイントは右側の「管理職区分」で、
12月には人事異動があったのでしょうか、
「課長」に当たる人が一人もいなくなっています。

#### 作成するグラフの紹介
作りたいのはこのようなダッシュボードです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/1613485d-ff1a-4071-d249-1487494ca9c9.png)

左側は12月の月ごとの売上の棒グラフで、
右側は11月、12月両方表示した年間の売上をクロス集計表にしています。

で、ここに「管理職区分」による関連値フィルターを表示したいのですが、
ここでポイントがあります。

#### 関連値フィルターの設定

「管理職区分」フィルターをこのように設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/929f327e-5470-3b25-a4a9-b93ba8fa9da9.png)

「適用先ワークシート」で「選択したワークシート」を選び、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/de716805-2740-b0ae-1639-7e6e2c13e56e.png)

「年間」を選択します。

こうすることで、月ごとの棒グラフと年間のクロス集計に対して、
「管理職区分」フィルターが連動して動きます。

#### 問題となること
さて、ダッシュボードに表示しましょう。
以下のように、2つのVizを横に並べました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/c3d3e738-d8d4-9432-cf36-4aa741ca6b5d.png)

ここまではいいのですが、「管理職区分」フィルターをどのように配置するか、です。
ここで、左側の月ごとの売上棒グラフの▼ボタンから以下のようにフィルターを表示し、
「関連値のみ」に設定したとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/0072f8ca-7d82-35c3-e400-7a4c6636d437.png)

すると、このように、「課長」の値が表示されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/c4f4c27c-5658-5868-fbd5-9ec31747c4be.png)

しかし、年間売上のクロス集計表には、「課長」である人が存在するので、
これでは「課長」でフィルターすることができず困ってしまいます。

#### 解決策
解決方法はとてもシンプルで、「課長」がいる「年間売上」の方からフィルターを表示してあげるだけです。
以下は「年間売上」の▼ボタンから「管理職区分」フィルターを表示しました。
「関連値のみ」の設定がなされていますが、
ちゃんと「課長」が表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666377/f8b693b2-fb5b-2900-aa4f-cbf010ac527d.png)


### まとめ
以上、私が実務で行き詰まった点の紹介でした。
分かる人からみれば「当たり前のこと」なのですが、
関連値フィルターを使う思わぬ不具合を招くことが多いので、
関連値フィルターの使用には十分注意しましょう。
パフォーマンスへの影響も考えると、
関連値フィルターの使用は最小限にした方がよいと思われます。
以上、最後まで読んでくださりありがとうございました！

Rieko
【Apache 2.4 ＋ Laravel】特定APIにアップロードファイルの上限指定する方法


# 【Apache 2.4 ＋ Laravel】特定APIにアップロードファイルの上限指定する方法

## 概要
特定のWebAPIのみ、アップロードするファイルサイズ上限を上げる手順を
備忘録として残します。

#### 環境
・Apache 2.4
・Laravel

#### 手順
LaravelプロジェクトのPublic配下にある```.htaccess```ファイルにて
下記を追記します。

###### 例）```post/create```に設定する場合
```
     <If "%{THE_REQUEST} =~ /.*post\x2Fcreate.*/">
         php_value post_max_size 500M
         php_value upload_max_filesize 500M
     </If>
```
以上です。

当初、```REQUEST_URI```を使用しようと考えましたが
Laravelの場合、```index.php```へリダイレクトされるため
 ```REQUEST_URI```が```index.php```となり使用できませんでした。

その中で、調べていくと```THE_REQUEST```を発見しこちらを使用することにしました。
```REQUEST_URI```はリクエストのURI部分が取得されるのに対し、```THE_REQUEST```はメソッドなども含まれるため正規表現で特定のURIに対応させています。

#### 参考
[Apache HTTP Serverの変数一覧](https://senooken.jp/post/2020/09/09/4382/)
[\<If\> ディレクティブ](https://httpd.apache.org/docs/2.4/ja/mod/core.html#if)
[Overview of new features in Apache HTTP Server 2.4](https://httpd.apache.org/docs/2.4/ja/new_features_2_4.html#:~:text=Per%2Drequest%20configuration%20sections)
0から始めるDjango開発(Part2) ユーティリティコマンドとは？？

# ユーティリティコマンドについて
Djangoにはdjango-adminとmanage.pyという二種類のユーティリティコマンドがある。
前者はプロジェクト作成時しか使わないのに対し、後者はDjangoアプリケーションの作成だけでなく、様々な場面で使う。

## django-adminコマンド
- __Djangoプロジェクトの作成__
```
% django-admin startproject <プロジェクト名>
```

## manage.pyコマンド
- __Djangoアプリケーションの自動作成__
```
% python manage.py startapp <アプリケーション名>
```

- __runserverの起動__
```
% python manage.py runserver
```

__マイグレーション__: 
Djangoにおけるmigrationは、モデルの定義をDBスキーマ(テーブルやカラムの構造)に反映させるための仕組みで、簡単に言うと、DjangoモデルとDBの状態を同期させるために使う。

- __マイグレーションファイルの作成__
```
% python manage.py makemigrations
```
- __マイグレーションの実行__
```
% python manage.py migrate
```

__マイグレーションのロールバック:__
Djangoのmigrationのrollbackは、DBのスキーマ(構造)を過去の状態に戻す作業を指す。
これにより、誤った変更や不要になった変更を元に戻すことができる。

- __マイグレーション状況の確認__
```
% python manage.py showmigrations <アプリケーション名>
app
[X] 0001_initial
[X] 0002_students
[ ] 0003_classes
[ ] 0004_test
```

- __マイグレーションのロールバック実行(0001_initial適用直後までもどす)__
```
% python manage.py migrate <アプリケーション名> 0001_initial
```
- __マイグレーション状況の確認(ロールバックできているか確認)__
```
% python manage.py showmigrations <アプリケーション名>
app
[X] 0001_initial
[ ] 0002_students
[ ] 0003_classes
[ ] 0004_test
```

## スーパーユーザーの作成
サイト管理者の作成コマンド
```
% python manage.py createsuperuser
username: admin
mailadress: admin@example.com
Password:
Password (again):
Superuser created successfully.
```

## テストコードの実施
```
% python manage.py test
```

## 全てのコマンドの確認
以下のコマンドを実行することで、利用可能なすべてのコマンドを一覧表示できる
```
% python manage.py help
```
0から始めるDjango開発(Part1) Djangoとは？？

# Djangoの全体像
Djangoの構成要素（コンポーネント）は主に次のようなものがある。
- ルーティング(Rooting)
- ビュー(View)
- フォーム(Form)
- モデル(Model)
- テンプレート(Template)

一般的にMVTモデルと呼ばれる

## 全体の処理の流れ
1\. ユーザーからのリクエストに含まれるURLから処理を任せるアプリケーションを識別して、処理を渡す。
2\. URLから処理すべきViewを識別して、処理を渡す。
3\. Formのコンポーネントを利用している場合にFormに処理を渡す。
4\. FormオブジェクトをViewに返す。
5\. DBとの連携が必要であればModelに処理を渡す。
6\. DBに対してSQLを発行。
7\. DBに対する処理結果をModelに返す。
8\. DBの処理結果をViewに返す
9\. HTML生成をTemplateに命令し、その際、フォームオブジェクトあるいはDBから取得した結果があれば渡す。
10\. 生成したHTMLをViewに返す。
11\. HTMLをレスポンスとしてユーザーに返す。

## Djangoプロジェクトのファイル構成
project: プロジェクト全体をまとめるディレクトリ
- application: アプリケーション関連ファイルをまとめるディレクトリ
    - migrations: migrationファイルを格納するディレクトリ
    - templates: Templateファイルを格納するディレクトリ
        - index.html: Templateファイル
    - __ init __.py: Pythonのパッケージを示すファイル（空で良い）
    - admin.py: 管理サイトの設定ファイル
    - apps.py: アプリケーション構成設定ファイル
    - forms.py: Form定義ファイル
    - models.py: Model定義ファイル
    - tests.py: テストコード記述ファイル
    - urls.py: アプリケーション用ルーティング定義ファイル
    - views.py: View定義ファイル
- project: プロジェクト全体に関わるファイルをまとめるディレクトリ
    - __ init__.py:
    - asgi.py: デプロイ用ファイル
    - settings.py: プロジェクト設定ファイル
    - urls.py: プロジェクト用ルーティング定義ファイル
    - wsgi.py: デプロイ用ファイル
- manage.py: コマンド実行用ファイル

## 各コンポーネントの役割
Rooting: URLからどのアプリケーションまたはビューに処理を渡すかを識別する。

View: 司令塔の役割を果たし、ModelにDB操作を指示したり、Templateに表示用データを渡してHTML生成を指示したりする。

Form: フォーム画面で入力されたユーザー入力値をフォームオブジェクトに変換して、DBに保管する。また、入力値のValidationも行う。

Model: DBとの連携を受け持つ。Viewから指示を受けると、その裏でSQLを発行し、DBの更新や検索結果をViewに返したりする。

Template: Viewから指示を受けると、HTMLの雛形にViewから受け取るDBの処理結果などを埋め込んで、HTMLを作成してViewに返す。
【Blender To Unity】オブジェクトのTransform適用時や結合時などに面が裏返ってしまう

# 【問題点】
　Blenderで作成したオブジェクトのTransform値を適用した際に、面が裏返ってしまいます。

(顔の中心線で真っ二つに割れたスザンヌ君を一括選択し、Transform値を適用する)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/28a39844-0f3a-a1a2-594a-8af856943fb4.png)

↓

(片側だけ面が裏返ってしまう)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/ba39da59-7847-da66-a189-0e6f9f32163e.png)


# 【回答】

　TransformのScale内にマイナス値があると面が裏返ります。
※同様の現象はTransform値を適用した際だけでなく、オブジェクトの結合時等にも発生します。

 (顔の左側ではTransform値内でScaleにマイナスの値がないため、適用しても面は裏返らない)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/1dde65fe-afd9-9ef8-d443-6e1cccd1f86f.png)

(顔の右側ではTransform値内でScaleにマイナスの値があるため、適用すると面が裏返る)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/6ee81bd3-a8a4-cdce-6269-87c38bc627c2.png)

↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/dd38e60a-5748-048f-98a1-1b70877daa17.png)

Scale値にマイナスが入る要因として、(私が確認できている限りでは)オブジェクトを反転させた場合(Mirrorを使用した場合)が挙げられます。

※ModifierのMirrorではなく、上部メニューバー > Object内にあるMirrorです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/8a1aa522-030c-5855-aaf0-913042a30591.png)

# 【解決策】
　Mirrorを使用した際に、こまめにTransform値を適用するに限ります。
 　また、裏返った面はUnity上で表示されないので、面を再度裏返してください。以下の記事の【準備】④を参考にしてください。

https://qiita.com/fuji_kyoto_kc/items/57697feac48ad83fd706
 
　こればかりは、私自身もより有効な解決策を知らないので、Mirrorを使った際はすぐTransformを適用するようにしています...。すみません...。
 　適用や結合した後に、面を裏返すようにするのも問題ないですが、裏返す面と裏返さない面の切り分けがかなり面倒くさいので上記の方法でやるのが一番だと思います。
springとmybatisでトランザクションを使う。

## springでトランザクション管理方法
①　Programmatic方式
PlatformTransactionManagerを使い、手動でトランザクションを開始・コミット・ロールバック。
②　Declarative方式（宣言的）
Transactionalアノテーションを使い、Springフレームワークが自動的にトランザクション管理を行ってくれる。

## programmatic vs declarative
一般的には宣言的な方法が簡単で便利。特別な制御が必要な場合にはプログラマティックな方法を使う。
1メソッド１坊式で使える。混ぜて使えない。

## ①　Programmatic方式の例
```
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class MyService {
    @AutoWired
    PlatformTransactionManager transactionManager;

    public void 単純なビジネスロジックメソッド() {
        // トランザクション定義の設定
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  // トランザクションの伝播設定

        // トランザクションを開始
        TransactionStatus status = transactionManager.getTransaction(def);

        try {
            // ビジネスロジックの実行
            someRepository.save(entity);//mybatis Repository
            anotherRepository.update(entity);//mybatis Repository

            // トランザクションをコミット
            transactionManager.commit(status);
        } catch (Exception ex) {
            // 例外発生時にはロールバック
            transactionManager.rollback(status);
            throw ex;
        }
    }
}

```


## PlatformTransactionManagerのトランザクション定義とトランザクションの伝播設定？

### DefaultTransactionDefinition
トランザクション管理の中で、トランザクションの動作を設定するためのインターフェース。
トランザクション定義の主な設定項目は伝播（Propagation）、タイムアウト、分離レベルなどがある。

### TransactionStatus
PlatformTransactionManagerのgetTransaction()メソッドを呼び出してトランザクションを開始する。この時、TransactionStatus オブジェクトが返却され、トランザクションの状態や管理情報を保持できる。

### Propagation
伝播とは、メソッドが呼び出されたときにそのメソッドがすでにトランザクション内で実行されているかを基準でそのメソッドのトランザクションの動作を決定すること。

伝播の主な種類
・PROPAGATION_REQUIRED: 既存のトランザクションがあればそれを使用し、なければ新しいトランザクションを開始。
・PROPAGATION_NEVER: そのメソッドが実行されるときに、もしすでにトランザクションが存在していたら、IllegalTransactionStateException がスローされる。

上記二つ以外にもたくさん。



## ②　Declarative方式の例
```
import org.springframework.transaction.annotation.Transactional;

public class MyService {

    @Transactional
    public void 単純なビジネスロジックメソッド() {
        someRepository.save(entity);//mybatis Repository
        anotherRepository.update(entity);//mybatis Repository
    }
}

```

## Transactionalのトランザクション定義とトランザクションの伝播設定？
Transactionalアノテーションのパラメーターに書く。こんな感じ。
```
@Transactional(propagation = Propagation.NEVER)
public void someMethod() {
    // 他にトランザクションが既に存在すると例外が発生
}
```

#### （　・。。・　）🖐

間違っている内容がありましたら、教えて頂ければ喜びます。
プリザンターのダッシュボード上でPlantUMLを表示する

# はじめに
本内容はプリザンターのダッシュボードにPlantUMLでUMLを書く時のサンプルとなります。
プリザンター構築のアイデアの一つになれば幸いです。

https://plantuml.com/ja/

## 環境
OS：windows 11 pro
DB：SQL Server 2019
プリザンター：1.4.6.1

# 手順

## １．前提

* 予めプリザンターにダッシュボードを作成
* 今回は[PlantUml](https://plantuml.com/ja/)から[サンプルにあるアクティビティ図](https://editor.plantuml.com/uml/SoWkIImgAStDuG8pk8hBCqkICnGqIbABI-mrkP8JYrCLD1IIy_DICaioy_CK71KqkHGKh49IAqeK3AqnvPqKD1NW2eomA716Ci0OYxmBahm95dbN97bJQwxKl1I8au7kpo_WSW3oGPu10000)を利用
    * 赤枠部分のSVGImageをクリックし、URLを控える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/190cbfea-cbd4-5330-978d-431b671697b8.png)

## ２．プリザンターの設定
予めプリザンターにダッシュボードを作成し、「管理」→「ダッシュボードの管理」へ進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/d5f7dcf4-fb68-ed7d-b257-07c0fc944388.png)

ダッシュボードパーツを選択し「新規作成」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/69ca1973-0b56-ac8c-a768-727467c58c22.png)

パーツタイプをカスタムHTMLに変更し、内容にPlantUMLのSVGアドレスをimgタグで囲みます。更新を押してダッシュボード画面に遷移すると登録したアクティビティ図が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/a01a127c-377e-1fdc-5ef7-bc4b7243c23f.png)

#### 内容に登録したタグ

```html
<p><img src="https://img.plantuml.biz/plantuml/png/SoWkIImgAStDuG8pk8hBCqkICnGqIbABI-mrkP8JYrCLD1IIy_DICaioy_CK71KqkHGKh49IAqeK3AqnvPqKD1NW2eomA716Ci0OYxmBahm95dbN97bJQwxKl1I8au7kpo_WSW3oGPu10000" alt="サンプル"></p>
```

### 実際の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/db553b38-0024-cbb3-9743-77b212d210c1.png)
LaTeX Missing number, treated as zero. 【電子情報通信学会 テンプレート】

# はじめに
研究会に参加することが決まりこれまでの成果を$\LaTeX$でまとめていたところ，見慣れないエラーが発生した．使用していたテンプレートは以下のリンクにあるものです．

https://www.ieice.org/jpn_r/event/kenkyukai/index.html?id=happyo#teishutu

エラー内容は下記のものです．

```
Missing number, treated as zero.
A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)
```

エラーメッセージを読むと，「数字が入るべき場所に入っていない」とのこと．「'weird error'で検索してね」とあるが，検索しても原因は判明せず……

最終的に解決するまでになんやこうやで1時間ほどかかってしまったので，将来の自分や他の誰かのために書き残しておきます．


# 発生した状況
今回のエラーはBibTeXを導入したところから発生しました．具体的には`.bst`ファイルを導入し，`.bib`ファイルに記載されているラベルを`\cite`で呼び出したところ発生しました．

当初は「BibTeXの導入方法をミスったかな」と思い，最初からやり直すことに．しかし，解決せず……


# 原因
なんやこうやでブラウザのハイパーリンクの色がほとんど変わってきたところで，ChatGPTに訊いてみました．すると，「`\href`が原因じゃね？」との返答が．

その助言に従って`\usepackage{href}`をコメントアウトすると，エラーが消えたではありませんか．
なぜ，`\href`が`\cite`を邪魔していたのかは分かりませんが，私の場合はこれが原因でした．

:::note
（ちょっとした小話）
`\href`が原因であると辿り着くまでにChatGPTに訊いてはみたのですが，その際はChatGPTに検索を許可していました．その際は`.bst`ファイルが読み込めていないのではないか？のような既に確認した内容の返答ばかり繰り返し，役に立たず……
思いつきでモデルが持つ知識のみを使って回答させたところ，今回の原因に辿り着きました．Web検索を許可する方が良い回答を生成することが多いイメージでしたが，場合によりけりですね．良い勉強になりました．
:::


# 対処方法
さて，BibTeXを利用するために`\href`が利用できなくなったわけですが，リンクを参考として差し込みたい……
そんな訳で調査していたところ，この方の記事を発見しました．

https://qiita.com/fuku_uma/items/185c8694486db945f4f7

BibTeXに`@webpage`という属性があるのを初めて知りました．


# 最後に
どなたかの役に立てばと思います．
Laravelでのアノテーションの書き方ミスについて

# はじめに
とあるwebシステムでLaravelを10から11にアップグレードする際、lint-testにて以下のようなエラーが出ました。その際にアノテーションで型指定をより明確にして解決しようとしたのですが、アノテーションの書き方で凡ミスがあったので繰り返さないようにここに記しておこうと思います。
*以下のエラーの対処法の記事ではありません。

```
Method App\Models\Sample::files() return type with       
generic class Illuminate\Database\Eloquent\Relations\HasMany does not  
specify its types: TRelatedModel, TDeclaringModel
```

# アノテーションの書き方ミス
以下のコードで、sampleTest()の戻り値に対してアノテーションを記述したのですが、うまくいきませんでした。原因は、メソッド内にアノテーションを記述してしまったこと。
```
  public function sampleTests(): HasMany
    {
       /**
       * @return HasMany<SampleTest, $this>
       */
        return $this->hasMany(SampleTest::class);
    }
```

通常アノテーションはメソッドの戻り値や引数の説明に用いられるもので、メソッド本体内に記述しても、アノテーションを解析するツールがメソッドの戻り値として扱ってくれないようです。そのため、以下のようにメソッド外にアノテーションを記述して、アノテーションがメソッド全体に対して説明することで、メソッドの戻り値の型を正しく解釈できるようです。
```
    /**
    * @return HasMany<SampleTest, $this>
    */
    public function sampleTests(): HasMany
    {
        return $this->hasMany(SampleTest::class);
    }
```

# あとがき
アノテーションとは、PHPのフレームワークであるLaravelにおいてはPHPDoc（PHPで使用される特定形式のドキュメントコメント）と言うようですね。他の言語やフレームワークでは、また別の構文のようです。また一つ、学ぶことができました。
ngrokの固定URLは無料プランで使える！設定方法をサクッと解説

ローカル開発をしていると、外部から一時的にアクセス可能にする方法として ngrok を使う機会が多いですよね。モックを見せるときや、LIFFアプリ開発の検証などに便利です。

しかし、「無料プランでは固定URLが利用できない」と誤解されている方も多いのではないでしょうか。実際、僕もその一人でした。

ところが、いつからか無料プランでも固定URLが使えるようになっていたんです！この記事では、その設定方法をサクッと解説します。

- コンソールにログイン > Domains > Create Domain をクリック

![スクリーンショット 2025-01-26 17.30.06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3994399/473014aa-1683-bedf-56d4-df5ad273934e.jpeg)

ランダムURLと固定URLを使い分けて、効率的な開発環境を整えることができました。
MSA切り替えのための通信・トランジェクションパターン


## 通信パターン  
分解されたサービス間でどのように通信するかを決定するためのパターン、つまり「通信」を解決するためのパターンです。


### 1. 同期パターン (Sync Pattern)  
あるサービスが他のサービスに特定のリクエストを送信し、そのレスポンスを受け取るまで処理を停止しても問題ない場合に使用します。  
主に以下の技術が使用されます：  
- **HTTP（Restful）**  
- **gRPC**

---

### 2. 非同期パターン (Async Pattern)  
あるサービスが他のサービスに特定のリクエストを送信した後、そのレスポンスを即座に受け取る必要がない場合に使用します。  
以下の技術が一般的に利用されます：  
- **Kafka** などの **メッセージキュー**  
- **Callback**  
- **Polling** など

---

## トランザクションパターン  
MSA環境で「トランザクション」を解決するためのパターンです。

### 1. 2PC（2Phase Commit）  
トランザクションの完了を2（N）段階で決定する方法です。  

- **1フェーズ（Commit Request）**: トランザクションの準備段階としてコミットリクエストを送信します。  
- **2フェーズ**: 各サービスの結果を確認し、すべてが成功した場合にコミットを実行。失敗した場合は全体をロールバックします。

ただし、このプロセスを管理するコーディネーターが必要であり、リクエスト送信自体が失敗する可能性があるため、不安定で古典的な方法とされています。

**例**:  
1つのトランザクションに2つのコミットリクエストが含まれる場合、最初のサービスは正常にコミットリクエストを送信したが、2番目のサービスでエラーが発生してロールバックリクエストを送信。しかし、最初のサービスへのロールバックリクエストが失敗する可能性があります。

---

### 2. 補償トランザクション (Compensating Transactions)  
特定のリクエストが正常終了した後、そのアクション（トランザクション）を元の状態に戻すためのアクション（トランザクション）です。

- 2PCの欠点を補う形で登場した方法です。  
- たとえば、2番目のサービスが失敗した場合、影響を受けたすべてのサービスに補償トランザクションを送信します。  
- ただし、補償トランザクション自体が失敗する可能性もあります。

---

### 3. サガパターン (Saga Pattern)  
トランザクションの前後関係を事前に定義し、必要に応じてコーディネーターが補償トランザクションを利用して管理することで、分散システム環境でトランザクションを実現するパターンです。

**動作例**:  
1. 最初のサービスが完了すると、サガを作成し、コーディネーターにイベントを発行します。  
2. 次のサービスでエラーが発生した場合、コーディネーターに問題を共有します。  
3. コーディネーターは、トランザクションが1つにまとめられていることを認識し、最初のサービスに補償トランザクションを送信します。  
4. サガが一定時間内に終了しない場合でも、補償トランザクションを送信できます。
🌐 NATインスタンスでプライベートサブネットをネットに繋げよう

# 🌟 NATインスタンスってなに？簡単に説明するよ！

NAT（ナット）インスタンスは、家の「Wi-Fiルーター」みたいなものだよ🏠✨

家の中にあるいろんなデバイス（スマホやパソコン）が、外のインターネットとやり取りできるのは、このWi-Fiルーターのおかげ。

NATインスタンスも同じように、内部のコンピュータが外の世界（インターネット）と通信できるよう手助けしているんだ🤖

# 🌐 Internet Gateway との関係

似たような概念で、Internet Gateway とは何が違うんでしょうか？

AWSでは、サブネットごとにインターネット接続の方法が異なります：

| 接続方法               | 対象サブネット         | 特徴                                                                                     |
|------------------------|------------------------|-----------------------------------------------------------------------------------------|
| Internet Gateway | パブリックサブネット   | パブリックIPを持つインスタンスが直接インターネットにアクセスします。                     |
| NAT Gateway/NAT Instance | プライベートサブネット | プライベートIPのみのインスタンスが、NATを通してインターネットにアクセスします。         |                           |

# 🌍 NAT Gatewayとの違い

似たような概念で、NAT GatewayとNAT Instanceは何が違うんでしょうか？

AWSでプライベートサブネットからインターネットに接続する場合、NAT Gateway または NAT Instance を使用します。

どちらを選ぶべきか、それぞれの特徴を見てみましょう。

##### NAT Gateway

大規模で安定したインフラが必要な場合

* マネージドサービス
* 高可用性と自動スケーリング
* 帯域幅の自動調整
* メンテナンスが不要
* 設定が比較的簡単
* やや高コスト

##### NAT Instance

コスト重視で、カスタマイズ性を求める場合

* EC2インスタンスベース
* 手動で管理が必要
* インスタンスタイプによる性能制限
* カスタマイズ性が高い
* コスト効率が良い
* セキュリティグループの設定が柔軟

個人開発や検証用環境ならNAT Instanceで十分かもね☺️

# 🔧 インスタンスをNAT化してみよう

Amazon Linux 2023を使ってNATインスタンスを作ってみよう💪

# 1️⃣ インターネットを通す「道」を作る

NATインスタンスが、データを中継できるように設定するよ。

```bash
sudo sysctl -w net.ipv4.ip_forward=1 | sudo tee -a /etc/sysctl.conf
```

💡 簡単に言うと
これで、「データを通してもいいよ！」とNATインスタンスに許可するんだ。

# 2️⃣ 「箱」を作る（テーブルの作成）

次に、データを整理する「箱」を用意するよ。これを テーブル って呼ぶんだ。

```bash
sudo nft add table nat
```

# 3️⃣ 入ってくるデータを処理する「入り口」を作る

NATインスタンスに届くデータを整理するための「入り口」を用意するよ。

```bash
sudo nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }
```

# 4️⃣ 出ていくデータを処理する「出口」を作る

データを外に送り出すための「出口」を作るよ。

```bash
sudo nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
```

# 5️⃣ データを外に送るための「ルール」を作る

ここがとっても大事！「マスカレード」という設定をして、内部のコンピュータが一つのIPアドレスを使って外部と通信できるようにするよ。

```bash
sudo nft add rule nat postrouting oifname "$(ip -o link show | awk -F': ' '/device-number-0/{print $2}')" masquerade
```

# 6️⃣ 今の設定を保存する

ここまでの設定を忘れないようにファイルに保存しよう！

```bash
sudo nft list table nat | sudo tee /etc/nftables/al2023-nat.nft
```

# 7️⃣ システムに設定を教える

さっき保存した設定をシステムが読み込むように教えてあげるよ。

```
echo 'include "/etc/nftables/al2023-nat.nft"' | sudo tee -a /etc/sysconfig/nftables.conf
```

8️⃣ NATインスタンスを「動かす」

設定が終わったら、NATインスタンスをスタートしよう！

```bash
sudo systemctl start nftables
```

9️⃣ システム起動時に自動スタート！

最後に、この設定がコンピュータを再起動しても動くようにするよ。

```
sudo systemctl enable nftables
```

🎉 お疲れさま

これで、NATインスタンスが「Wi-Fiルーター」のように働いて、内部のコンピュータが外のインターネットと安全に通信できるようになったよ😊✨
next/navigationにお世話になります

## next/navigationとは
Next.jsのクライアントサイドナビゲーション機能を提供するモジュールです。

## 主な機能：

### useSearchParams()
URLのクエリパラメータを取得
例：?q=検索ワード から "検索ワード" を取得
### useRouter()
プログラムによるページ遷移
クエリパラメータの操作
### usePathname()
現在のURLパス取得

```
const searchParams = useSearchParams();
const query = searchParams.get('q'); // URLの?q=値 を取得
```
Jest Loading エラーの解決方法について

# はじめに
jestでLoadingが表示されることについてテストを実装した際、下記のようなエラーが表示されました。
こちらの解決方法について共有させていただきます。

```terminal Console
App › Loading...が表示されること

    expect(element).toBeInTheDocument()

    element could not be found in the document

      36 |     
      37 |     const Loading = await waitFor(() => screen.getByText("Loading..."));
    > 38 |     expect(Loading).toBeInTheDocument();
         |                     ^
      39 |   });
      40 |
      41 |   test("タイトルがあること", async () => {

      at Object.<anonymous> (src/__tests__/Todo.spec.tsx:38:21)
```
Loadingの要素を取得できていないようです。
<br>
```App.tsx
useEffect(() => {
    const fetchTodos = async () => {
      setLoading(true);
      try {
        await new Promise((resolve) => setTimeout(resolve, 500)); // ← こちらを追加
        const data = await GetAllTodos();
```
上記を追加することで解決できました。
GetAllTodosが実行されるまでの時間が短いため、テストでLoadingの要素を取得できていなかったようです。

## 参考
https://qiita.com/cheez921/items/41b744e4e002b966391a

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp
【Rails初心者学習記録】いいね機能を実装してみた

# 【Rails初心者学習記録】いいね機能を実装してみた

## はじめに
Railsで「いいね機能」を実装した際の学習記録です。
ハートマークをクリックすることで、いいねしたり、いいねを消したりできる機能を実装しました。

## 1. いいね機能の設計
いいね機能は、ユーザーが投稿に対して1回だけ「いいね！」をつけたり外したりできる仕組みです。

1. `favorites` テーブルを作成する
2. `favorites` テーブルを中間テーブルとして使い、`User`と`Post`の間に多対多のリレーションを作成する
3. ビューにいいねボタンを設置し、`create` と `destroy` のアクションで管理する

## 2. モデルとテーブルの作成
まず、いいねを管理する `favorites` テーブルを作成します。

```sh
rails g model Favorite user_id:integer post_id:integer
rails db:migrate
```

## 3. アソシエーションの設定
`app/models/user.rb`:

```ruby
class User < ApplicationRecord
  has_many :favorites, dependent: :destroy
end
```

`app/models/post.rb`:

```ruby
class Post < ApplicationRecord
  has_many :favorites, dependent: :destroy

  def favorited_by?(user)
   favorites.where(user_id: user.id).exists?
  end
end
```

`app/models/favorite.rb`:

```ruby
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
```

## 4. コントローラーの実装
`app/controllers/favorites_controller.rb`:

```ruby
class FavoritesController < ApplicationController
  def create
    post = Post.find(params[:post_id])
    favorite = current_user.favorites.new(post_id: post.id)
    favorite.save
    redirect_to post_path(post)
  end
      
  def destroy
    post = Post.find(params[:post_id])
    favorite = current_user.favorites.find_by(post_id: post.id)
    favorite.destroy
    redirect_to post_path(post)
  end
end
```

## 5. ルーティングの設定
`config/routes.rb`:

```ruby
resources :posts do
  resource :favorite, only: [:create, :destroy]
end
```
※いいねidの受け渡しが不要なので、resourceと単数にした。

## 6. ビューの実装
`app/views/posts/_post.html.erb`:

```erb
<p class="caption"><%= @post.任意の項目 %>
  <% if @post.favorited_by?(current_user) %>
    <%= link_to post_favorites_path(@post),  data: { turbo_method: :delete }, class: "favorite_btn" do %>
     ♥<%= @post.favorites.count %> いいね
    <% end %>
  <% else %>
    <%= link_to post_favorites_path(@post),  data: { turbo_method: :post }, class: "favorite_btn" do %>
     ♡<%= @post.favorites.count %> いいね
    <% end %>
  <% end %>
</p>
```

## 最後に
今後はAjaxを使って非同期処理を実装したいです！
最後まで読んでいただきありがとうございました！