LoginSignup
2
0

More than 3 years have passed since last update.

【Rails】SessionsHelperを使ってコントローラー間でパラメータを受け継ぐ

Posted at

はじめに

某プログラミングスクールでフリマアプリを作成中、購入内容の確認ページからクレジットカード登録ページに遷移。カード登録後、購入内容の確認ページに遷移することが出来なくなった。

原因:コントローラーがitems_controller.rbからcredit_cards_controller.rbに変わった時点でパラメータの:item_idが0になっていた。

詳細

  1. ユーザーログイン後、routingでトップページ(items#index)へ遷移。
  2. 他ユーザーの出品商品(items#create)の詳細ページ(items#show)へ遷移。
  3. 詳細ページ(items#show)の購入ボタンより商品購入ページ(items#purchase)へ遷移。
  4. クレジットカード情報の登録・変更するために、登録・変更ボタンより(credit_cards#index)へ遷移。
    1. 遷移したが変更がなければ、もどるボタンで商品購入ページ(items#purchase)へ遷移。
    2. 変更・未登録ならカード登録ページ(credit_cards#new,create)に遷移後,(credit_cards#show)に遷移。その後カード決定・もどるボタンより商品購入ページ(items#purchase)へ遷移。
  resources :items, only: [:index, :new, :create, :show, :edit, :destroy] do
    get '/purchase/:id', to: 'items#purchase', as: :purchase
  end
  resources :credit_cards, only: [:index, :new, :create, :show, :destroy]

スクリーンショット 2020-10-11 13.37.34.png

5. 4-1,4-2にてitem_idがないというErrorが発生した

スクリーンショット 2020-10-11 13.58.34.png

ターミナルで確認するとitem_idがcontrollerを跨ぐタイミングで消えている。

Processing by ItemsController#purchase as HTML
  Parameters: {"item_id"=>"2"}
  Item Load (0.3ms)  SELECT  `items`.* FROM `items` WHERE `items`.`id` = 2 LIMIT 1
Processing by CreditCardsController#show as HTML

実装内容

item_idを引き継ぐ方法を検索していたところ...

【Rails】Sessionの使い方について
Ruby on Rails チュートリアル - セッション

sessionが使えそうだと判断。
はじめにapplication_controller.rbにinclude SessionHelperを追加。

application_controller.rb
class ApplicationController < ActionController::Base
  include SessionsHelper #左記を追加
end

/app/helpersに/sessions_helper.rbを作成し、下記コードでSessionsHelperを呼び出し

/app/helpers/sessions_helper.rb
module SessionsHelper
end

参考記事
「初期化されていない定数ApplicationController :: SessionsHelper(NameError)」が表示されるのはなぜですか?

これでsessionの準備が完了

まず、sessionにitem_idを保存する。

app/controllers/items_controller.rb
def purchase
  @item = Item.find(params[:item_id]) #paramsからitem_idを取り出し
  session[:item_id] = @item #取り出したitem_idをsessionに保存
end

次に、credit_card登録先のcontroller(credit_cards#index,credit_cards#show)でsessionに保存していたパラメータを取り出す。
binding.pryで確認したところ配列になっていたので、valuesで取り出す。

app/controllers/credit_cards_controller.rb
#session[:item_id]で先ほどのsessionデータを取り出せる。
def index
  @item_id = session[:item_id].values.first 
end

def show
  @item_id = session[:item_id].values.first
end

controllerで作成したインスタンス変数(@item_id)をviewで取り出し

app/views/credit_cards/index.html.haml
= link_to "もどる", "/items/#{@item_id}/purchase", class:'return'
app/views/credit_cards/show.html.haml
%button.enter__permit__box.btn(onclick="location.href='/items/#{@item_id}/purchase'")選択した支払い方法を使う
= link_to "もどる", "/items/#{@item_id}/purchase", class:'return'

これで items#purchase ⇄ credit_cards#show,index において item_idのやりとりが出来るようになった。
最後に商品購入をした際に、sessionの削除をする

app/controllers/items_controller.rb
def pay
  session[:item_id] = nil
end

今回はsessionを使ってパラメータのやりとりを行なったがURLを使用してパラメータをやりとりできるみたいなので、今度試してみたい。

なお、sessionを使用する際は、それなりにリスクを伴うので、使用する際は下記のリンク先も合わせて読んでおきたい。

合わせて読みたい記事(セッションを取り扱う際の注意点)

Rails セキュリティガイド

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0