💡Railsガイド(通知機能)をよりわかりやすく

## Railsでの在庫通知メール機能の実装まとめ

---

### 📦 1 在庫トラッキング機能の追加

#### ✅ 目的
商品ごとに「在庫数」を管理できるようにする。これにより「在庫切れ」や「復活」の判定ができる。

#### ✅ 手順とコード

1 **マイグレーションの生成**（在庫数カラムを追加）
```bash
$ bin/rails generate migration AddInventoryCountToProducts inventory_count:integer
$ bin/rails db:migrate
```
2 **フォームに在庫入力欄を追加**
```erb
<%= form.label :inventory_count %>
<%= form.number_field :inventory_count %>
```

このフィールドで在庫数を入力できるようになります。

3 **Strong Parametersの更新**
```ruby
params.require(:product).permit(:name, :description, :featured_image, :inventory_count)
```

セキュリティのため、許可されたパラメータだけが保存されます。

4 **バリデーションを追加**
```ruby
validates :inventory_count, numericality: { greater_than_or_equal_to: 0 }
```

在庫数がマイナスにならないように制限します。

---

### 📧 2 購読者モデル（Subscriber）の追加

#### ✅ 目的
在庫切れ商品の「再入荷通知」を希望するユーザーのメールアドレスを保存する。

#### ✅ 手順とコード

1 **モデルとテーブルを作成**
```bash
$ bin/rails generate model Subscriber product:belongs_to email
$ bin/rails db:migrate
```
1つの商品に複数の購読者が紐づく（1対多の関係）ようになります。

2 **Productモデルに関連付け**
```ruby
has_many :subscribers, dependent: :destroy
```
商品が削除されたら、関連する購読者も削除されます。

3 **SubscribersControllerを作成**
```ruby
@product.subscribers.where(subscriber_params).first_or_create
```
すでに購読しているメールアドレスは重複登録されないようになっています。

4 **ルーティング設定**
```ruby
resources :products do
  resources :subscribers, only: [:create]
end
```
商品に紐づいた形で購読者を登録するため、ネストされたルーティングにします。

5 **フォーム表示**
```erb
<%= form_with model: [product, Subscriber.new] do |form| %>
  <%= form.email_field :email, placeholder: "you@example.com", required: true %>
  <%= form.submit "Submit" %>
<% end %>
```

---

### ✉️ 3 メール通知機能の追加

#### ✅ 目的
在庫が復活したときに、自動的に購読者にメールを送信する。

#### ✅ メーラーの作成と使用

1 **メーラーの作成**
```bash
$ bin/rails g mailer Product in_stock
```

2 **送信処理**
```ruby
mail to: params[:subscriber].email
```

3 **HTML/テキストメールのテンプレートを編集**
```erb
<p><%= link_to @product.name, product_url(@product) %> is back in stock.</p>
```
HTMLでは`product_url`を使って完全なリンクにします。

4 **モデルで通知処理を追加**
```ruby
after_update_commit :notify_subscribers, if: :back_in_stock?
```
在庫が「0 → 1以上」に変わったときだけ通知が送られるようになります。

---

### 🧩 4 Concernで通知処理を整理

#### ✅ 目的
モデルが肥大化しないよう、通知関連のロジックを切り出す。

#### ✅ Concernの作成
```ruby
module Product::Notifications
  extend ActiveSupport::Concern

  included do
    has_many :subscribers, dependent: :destroy
    after_update_commit :notify_subscribers, if: :back_in_stock?
  end
```

#### ✅ 利用方法
```ruby
class Product < ApplicationRecord
  include Product::Notifications
```
このように`include`することで、通知機能を再利用可能にします。

---

### 🔗 5 購読解除機能の実装

#### ✅ 目的
ユーザーが希望すれば、いつでも通知を解除できるようにする。

#### ✅ 解除用トークンとルーティング
```ruby
resource :unsubscribe, only: [:show]
```

```ruby
class Subscriber < ApplicationRecord
  generates_token_for :unsubscribe
```

#### ✅ コントローラ
```ruby
@subscriber = Subscriber.find_by_token_for(:unsubscribe, params[:token])
```
トークンが一致すれば購読を解除。

#### ✅ メールに解除リンクを追加
```erb
<%= link_to "Unsubscribe", unsubscribe_url(token: params[:subscriber].generate_token_for(:unsubscribe)) %>
```

ユーザーがこのリンクをクリックすると、購読情報が削除されます。

---

### ✅ 補足
- **ActionMailer**：Railsでメールを送る標準の機能。
- **Concern**：モデルの肥大化を防ぎ、共通機能を整理する手段。
- **Token認証**：セキュアな購読解除のための一時的なキーの仕組み。

実装しておけば、再入荷時の機会損失を減らすことができるのでおすすめ

---
### 参考文献
https://railsguides.jp/getting_started.html#propshaft