質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

5976閲覧

Rails sessionに保存された配列データを全て表示

shirou

総合スコア15

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

1グッド

1クリップ

投稿2018/08/12 08:31

前提・実現したいこと

前回の質問の続きになります。
商品を追加するたびに保存されるsession情報より、
sessionにて保存したデータを、カートの中身を表示するページにて全て出力させたい。

発生している問題・エラーメッセージ

デバッグにて session[:cart]の配列の中身を確認したところ、確かに商品追加を押すたびにitem.idが保存されていることが確認可能。
問題は

class CartController < ApplicationController def index @cart = Item.find(session[:cart]) end def create session[:cart] = [] unless session[:cart] session[:cart] << params[:item_id] flash[:success] = "カートに追加できました!" redirect_to root_path end end

にて Item.findが item.idに該当するItemを一回取得した段階で、以降の取得をなぜか拒絶する為

session[:cart] = [1,2,3,4,1,1,2,3,4,3,2]

sessionに保存されている内容が上記であった際に

@cartsのデバッグ結果 #<Item:0x00007fd5ad870200> #<Item:0x00007fd5ad870840> #<Item:0x00007fd5a911beb8> #<Item:0x00007fd5ad870520>

@cartの中身を確認すると一度しか取得されてない。

該当のソースコード

erb

1#index.html.erb 2<tbody> 3<h1>カートの中身</h1> 4<% sum = 0 %> 5<% @cart.each do |item| %> 6<tr> 7<td>商品番号: <%= item.id %></td> 8<td>価格: <%= item.price %></td><br> 9<% sum += item.price %> 10<% end %><br> 11合計金額: <%= sum %>12</tr> 13</tbody> 14<br> 15<%= link_to 'Check Products', root_path %>

ruby

1#cart.controller.rb 2class CartController < ApplicationController 3 def index 4 @cart = Item.find(session[:cart]) 5 end 6 7 def create 8 session[:cart] = [] unless session[:cart] 9 session[:cart] << params[:item_id] 10 flash[:success] = "カートに追加できました!" 11 redirect_to root_path 12 end 13 14end

試したこと

Item.findではなく、Item.whereで実行→whereの後に続くのは条件である為,session[:cart]は×
キーワードを変えてググったものの、状況が特殊である為かhitしなかったので断念。
そもそも商品の個数を考慮していないコードである為、当然の結果なのかもしれないが
「配列に保存された内容を表示する」ことは何ら問題のないことであると思う。
また、Item.find(session[:cart])でなければ、index.html.erbにて、item modelのメソッドを継承できない恐れがある為、現状ではどう変更すればいいかわかりません。。

補足情報(FW/ツールのバージョンなど)

Rails 5.2.0

zeta1978👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

現状のソースコード全体を見ていないので、妥当な解決策になっているか心もとないのですが、id が[1,2,3,4,1,1,2,3,4,3,2]
であるような Itemインスタンス計11個を @cart に、この id の配列順に入れたいのであれば、CartController#index で、

ruby

1@cart = Item.find(session[:cart])

としているところを、以下に変更してみるといかがでしょうか?

ruby

1@cart = session[:cart].map { |item_id| Item.find(item_id) }

投稿2018/08/12 12:09

jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shirou

2018/08/12 13:20

こんばんは! 以前も回答して頂き、今回も最適な回答をありがとうございます! Item.findからコードを書き始めなければならない・・と縛られていたように思います。 mapメソッドを使うことで配列の要素を一つづつItem.findに格納することで、まさにその通り、実現したい結果通りに動きました! ありがとうございます・・!
jun68ykt

2018/08/12 13:22

解決されたようですね、よかったです!
shirou

2018/08/13 05:20

配列順に入れるだけで,商品番号を考慮しないのはスマートではないと、回答を頂いてよりひっかかていたので ``` session[:cart].sort! @cart = session[:cart].map { |item_id| Item.find(item_id) } ``` sort!を追加することで商品の順番ごとの配列になりました!
jun68ykt

2018/08/15 05:58

おめでとうございます!
_shimada

2019/12/06 09:04

こういう場合の本来のwhereの使い方は Item.where(id: session[:cart]).order(:id) となります。 セッションに商品ID 1,2,3 が保存されていた場合、発行されるSQLは SELECT items.* FROM items WHERE items.id IN (1, 2, 3) ORDER BY items.id ASC となります。 ループを回してSQLを何度も発行しないようにしましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問