Railsでの在庫通知メール機能の実装まとめ(Markdown形式・解説つき)
📦 1 在庫トラッキング機能の追加
✅ 目的
商品ごとに「在庫数」を管理できるようにする。これにより「在庫切れ」や「復活」の判定ができる。
✅ 手順とコード
1 マイグレーションの生成(在庫数カラムを追加)
$ bin/rails generate migration AddInventoryCountToProducts inventory_count:integer
$ bin/rails db:migrate
2 フォームに在庫入力欄を追加
<%= form.label :inventory_count %>
<%= form.number_field :inventory_count %>
このフィールドで在庫数を入力できるようになります。
3 Strong Parametersの更新
params.require(:product).permit(:name, :description, :featured_image, :inventory_count)
セキュリティのため、許可されたパラメータだけが保存されます。
4 バリデーションを追加
validates :inventory_count, numericality: { greater_than_or_equal_to: 0 }
在庫数がマイナスにならないように制限します。
📧 2 購読者モデル(Subscriber)の追加
✅ 目的
在庫切れ商品の「再入荷通知」を希望するユーザーのメールアドレスを保存する。
✅ 手順とコード
1 モデルとテーブルを作成
$ bin/rails generate model Subscriber product:belongs_to email
$ bin/rails db:migrate
1つの商品に複数の購読者が紐づく(1対多の関係)ようになります。
2 Productモデルに関連付け
has_many :subscribers, dependent: :destroy
商品が削除されたら、関連する購読者も削除されます。
3 SubscribersControllerを作成
@product.subscribers.where(subscriber_params).first_or_create
すでに購読しているメールアドレスは重複登録されないようになっています。
4 ルーティング設定
resources :products do
resources :subscribers, only: [:create]
end
商品に紐づいた形で購読者を登録するため、ネストされたルーティングにします。
5 フォーム表示
<%= form_with model: [product, Subscriber.new] do |form| %>
<%= form.email_field :email, placeholder: "you@example.com", required: true %>
<%= form.submit "Submit" %>
<% end %>
✉️ 3 メール通知機能の追加
✅ 目的
在庫が復活したときに、自動的に購読者にメールを送信する。
✅ メーラーの作成と使用
1 メーラーの作成
$ bin/rails g mailer Product in_stock
2 送信処理
mail to: params[:subscriber].email
3 HTML/テキストメールのテンプレートを編集
<p><%= link_to @product.name, product_url(@product) %> is back in stock.</p>
HTMLではproduct_url
を使って完全なリンクにします。
4 モデルで通知処理を追加
after_update_commit :notify_subscribers, if: :back_in_stock?
在庫が「0 → 1以上」に変わったときだけ通知が送られるようになります。
🧩 4 Concernで通知処理を整理
✅ 目的
モデルが肥大化しないよう、通知関連のロジックを切り出す。
✅ Concernの作成
module Product::Notifications
extend ActiveSupport::Concern
included do
has_many :subscribers, dependent: :destroy
after_update_commit :notify_subscribers, if: :back_in_stock?
end
✅ 利用方法
class Product < ApplicationRecord
include Product::Notifications
このようにinclude
することで、通知機能を再利用可能にします。
🔗 5 購読解除機能の実装
✅ 目的
ユーザーが希望すれば、いつでも通知を解除できるようにする。
✅ 解除用トークンとルーティング
resource :unsubscribe, only: [:show]
class Subscriber < ApplicationRecord
generates_token_for :unsubscribe
✅ コントローラ
@subscriber = Subscriber.find_by_token_for(:unsubscribe, params[:token])
トークンが一致すれば購読を解除。
✅ メールに解除リンクを追加
<%= link_to "Unsubscribe", unsubscribe_url(token: params[:subscriber].generate_token_for(:unsubscribe)) %>
ユーザーがこのリンクをクリックすると、購読情報が削除されます。
✅ 補足
- ActionMailer:Railsでメールを送る標準の機能。
- Concern:モデルの肥大化を防ぎ、共通機能を整理する手段。
- Token認証:セキュアな購読解除のための一時的なキーの仕組み。
実装しておけば、再入荷時の機会損失を減らすことができるのでおすすめ
参考文献