はじめに
例によって、某プログラミングスクールの最終課題である、フリマアプリのクローンサイト作成において、購入機能実装時にPay.jpを利用したので、健忘録としてここに記す。
今回は「クレジットカード詳細表示・削除」の実装に取り掛かります。
バージョン情報
ruby '2.5.1'
Rails '5.2.4.2'
実装の流れ
- 実装の準備・APIの導入
- モデルの作成・クレジットカード登録
- クレジットカード詳細表示・削除 ← 今回の実装内容
- クレジットカード購入(決済)機能
前提条件として
- 記載はhaml記法で
- 私の参考にしたrailsにhamlを導入するやり方はこちら、、
- ユーザー登録機能として、gemの
devise
を利用しています。 なのでcurrent_user
などのdevise
のメソッドが随所に出てきます - 参考記事: 【Rails】deviseを導入してみる
今回の実装機能のダイジェスト
クレジットカード詳細表示から削除はこんな感じ
- クレジットカード詳細表示画面上で、登録クレジット会社のロゴ画像、カード番号末尾4桁、有効期限が表示される。
- 削除ボタンを押すと、登録情報が削除される
前置きはこれくらいで、いよいよ実装!
いよいよ実装! まずはコントローラーの記載
まずはコントローラーの記載を行います。
詳細表示機能はshowアクション
で、削除機能はdestroyアクション
で定義します。
controllers/credit_cards_controller.rb
require "payjp" # PAYJPとやり取りするために、payjpをロード
def new
# 前回のnewアクションに追記
# すでにクレジットカード登録されている場合は、showアクションにリダイレクト
@card = CreditCard.where(user_id: current_user.id)
redirect_to credit_card_path(current_user.id) if @card.exists?
end
# ここのcreateメソッドは前回と同じ
def create
Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)
if params["payjp_token"].blank?
redirect_to action: "new", alert: "クレジットカードを登録できませんでした。"
else
customer = Payjp::Customer.create(
email: current_user.email,
card: params["payjp_token"],
metadata: {user_id: current_user.id}
)
@card = CreditCard.new(user_id: current_user.id, customer_id: customer.id, card_id: customer.default_card)
if @card.save
else
redirect_to action: "create"
end
end
end
def show
# ログイン中のユーザーのクレジットカード登録の有無を判断
@card = CreditCard.find_by(user_id: current_user.id)
if @card.blank?
# 未登録なら新規登録画面に
redirect_to action: "new"
else
# 前前回credentials.yml.encに記載したAPI秘密鍵を呼び出します。
Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)
# ログインユーザーのクレジットカード情報からPay.jpに登録されているカスタマー情報を引き出す
customer = Payjp::Customer.retrieve(@card.customer_id)
# カスタマー情報からカードの情報を引き出す
@customer_card = customer.cards.retrieve(@card.card_id)
##カードのアイコン表示のための定義づけ
@card_brand = @customer_card.brand
case @card_brand
when "Visa"
# 例えば、Pay.jpからとってきたカード情報の、ブランドが"Visa"だった場合は返り値として
# (画像として登録されている)Visa.pngを返す
@card_src = "visa.png"
when "JCB"
@card_src = "jcb.png"
when "MasterCard"
@card_src = "master.png"
when "American Express"
@card_src = "amex.png"
when "Diners Club"
@card_src = "diners.png"
when "Discover"
@card_src = "discover.png"
end
# viewの記述を簡略化
## 有効期限'月'を定義
@exp_month = @customer_card.exp_month.to_s
## 有効期限'年'を定義
@exp_year = @customer_card.exp_year.to_s.slice(2,3)
end
end
def destroy
# ログイン中のユーザーのクレジットカード登録の有無を判断
@card = CreditCard.find_by(user_id: current_user.id)
if @card.blank?
# 未登録なら新規登録画面に
redirect_to action: "new"
else
# 前前回credentials.yml.encに記載したAPI秘密鍵を呼び出します。
Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)
# ログインユーザーのクレジットカード情報からPay.jpに登録されているカスタマー情報を引き出す
customer = Payjp::Customer.retrieve(@card.customer_id)
# そのカスタマー情報を消す
customer.delete
@card.delete
# 削除が完了しているか判断
if @card.destroy
# 削除完了していればdestroyのビューに移行
# destroyビューを作るのが面倒であれば、flashメッセージを入れてトップページやマイページに飛ばしてもOK
else
# 削除されなかった場合flashメッセージを表示させて、showのビューに移行
redirect_to credit_card_path(current_user.id), alert: "削除できませんでした。"
end
end
end
(例によって、フラッシュメッセージをしれっと入れてます)
参考にした記事: 【Rails】flashメッセージを使用して簡易メッセージを表示させる詳しい方法と解説
変更、追記内容としては
- newメソッドにクレジットカード登録済みの際にshowアクションに移るように定義
- (詳細表示機能として)showメソッドの定義。その際に
- viewで表示するクレジットカードのブランド画像を定義
- viewで表示するクレジットカード情報の有効期限の年と月を定義
- (削除機能として)destroyメソッドを定義
です。
ついでにルーティングも設定しておく
config/routes.rb
Rails.application.routes.draw do
# したの方に追記 :show, :destroyを追加で記述
resources :credit_cards, only: [:new, :create, :show, :destroy] do
end
end
これでパスが生成されたので、該当リンクに貼り付けます。
続いて、ビューの記載
ちなみに部分テンプレートを使用してます(ファイル名を参照!)。
showビューの記載
views/credit_cards/show/_show.html.haml
.show
.show__frame
.show__frame__title
登録クレジットカード情報
.credit_card__list
.credit_card__list__title
クレジットカード一覧
.credit_card__list__frame
.credit_card_info
.credit_card_info__brand
# showメソッドで定義した@card_srcを呼び出し
# 画像をcardsというフォルダを作り、入れておく
= image_tag "cards/#{@card_src}", class: "credit_card_info__brand__img", alt: @card_brand
.credit_card_info__numbers
.number
# Pay.jpから取得したカード番号の末尾4桁を取得
= "**** **** **** " + @customer_card.last4
.expiration_date
.expiration_date__title
有効期限
.expiration_date__info
# showメソッドで定義した有効期限の年と月を取得
= @exp_month + " / " + @exp_year
.destroy__function
.destroy__function__link
# 削除ボタンを作成、押すとdestroyメソッドが働くように
= link_to credit_card_path, method: :delete, class: "destroy__function__link__btn" do
削除する
.payment-details
= link_to "支払い方法について >", "", class: "payment-details__btn"
(お好みで実装)destroyビューの記載
views/credit_cards/destroy/_destroy.html.haml
.destoroy
.destoroy__frame
.destoroy__frame__message
削除が完了しました。
%ul.destoroy__frame__btns
%li.credit_card_new_link
= link_to "クレジットカード新規登録", new_credit_card_path, class: "credit_card_new_link__btn"
%li.my_page_link
= link_to "マイページに戻る", users_path(current_user.id), class: "my_page_link__btn"
特に言うことはありません、、、、
クレジット新規登録(newアクション
へのパス)をつけておけば、編集機能っぽくなるのかな?
クレジットカード詳細表示・削除機能 実装完了!!
最後に
以上でクレジットカードの詳細表示・削除機能の実装は完成です!
前回の新規登録機能よりかは難易度が下がったのではないでしょうか。
次回は、「クレジットカード購入(決済)機能」の実装を行います。