はじめに
カート機能を作成中です。 ”今回はカートに入れる”とカートに入るようにします。 同一商品の場合には、個数のみが更新されるようにします。前提条件
ここで登場するテーブル・モデルは、 Customer Item Cart_item です。←(CustomerとItemの中間テーブルになる。) (Cartモデルを作成している記事が多いですが、Cartモデルは作成していません。)*ログインしなくても商品の閲覧はできるが、カートには入れられない。
View 個数を選択してカートに入れる
#関係するところのみ抜粋
<%= form_with model:@cart_item,url:cart_items_path,method: :post,local:true do |f| %>
<%= f.hidden_field :item_id, value: @item.id %>
<%= f.hidden_field :customer_id, :value => current_customer.id %>
<%= f.select :quantity,[1,2,3,4,5,6,7,8,9,10],{include_blank: '個数選択'},required:true%> 
<%= f.submit 'カートに入れる' ,class: 'btn btn-success btn-sm'%><% end %>
hidden_fieldとは何?
複数のWebページ間でデータの受渡しを行う際に利用されます。
hiddenなので画面上には表示されません。
今回だと、カートの画面にcustomer_idとitem_idを渡しています。
エラーの記録:個数選択 無しで、カートに入れる は出来ないようにしたいのに
f.selectで、required:trueにしてますがこれは"入力必須"ということです。
しかしながら、"個数選択"のままカートに入れるボタンを押すことができ、nil~のようなエラーが出てきてしまいます。
モデルファイルのバリデーションでもpresense trueにしてて、数字のみ受け付けるようにしてたのですが、
nilで進んでしまい、nil~のエラーがでてました。
解決策
マイグレーションファイルでnil falseにしたら解決しました・・・コントローラー
cart_item_controller.rb
def create
@cart_item = CartItem.new(params_cart_item)
@cart_item.customer_id=current_customer.id
@cart_items=current_customer.cart_items.all
@cart_items.each do |cart_item|
if cart_item.item_id==@cart_item.item_id
new_quantity = cart_item.quantity + @cart_item.quantity
cart_item.update_attribute(:quantity, new_quantity)
@cart_item.delete
end
end
@cart_item.save
redirect_to cart_items_path,notice:"カートに商品が入りました"
end
private
def params_cart_item
params.require(:cart_item).permit(:quantity, :item_id,:customer_id)
end
解説
```@cart_item = CartItem.new(params_cart_item)``` 本の投稿と似てます。 Cart_itemの新規投稿。 ストロングパラメーターで、個数、item_id、customer_idを受け取っています。 ```@cart_item.customer_id=current_customer.id``` この記述は不要だったかもしれません。というのも、個数選択のviewで同じような定義をしてるからです。 ```@cart_items=current_customer.cart_items.all``` ここで、カートに入っているものを取り出しています。問題は次!同じ商品をまとめる記述
```@cart_items.each do |cart_item|``` カートの中身を一個ずつ取り出して、 ```if cart_item.item_id==@cart_item.item_id``` もし、同じ商品が存在していれば、 ```new_quantity = cart_item.quantity + @cart_item.quantity``` 今の個数に足す それを、new_quantityに代入。 ```cart_item.update_attribute(:quantity, new_quantity)``` cart_itemモデルのquantityをnew_quantityに更新するよ という意味らしい。 ```@cart_item.delete``` 同一商品に関しては、個数だけ更新できたら後はオサラバ参考にさせていただきました
以下の記事に感謝です 同じ商品がカートに入った場合、個数のみ更新されるよう記述できました。