🤝

共同開発備忘録リスト2

2024/06/23に公開

https://qiita.com/keijitsumori/items/f17a56a583a3c24a88a3

Validation failed: Item must exist
Extracted source (around line #9):

def create
@cart_item = current_customer.cart_items.new(cart_item_params)
@cart_item.save!
save出来てない。!で確認 item.idが入ってない
hidden_fieldで追加した。

f.hidden_field :保存したいカラム先, value: 保存したい値 

個数変更セレクトに現在のカートに入ってる各個数を初期値に設定する。

⭐️⭐️options_for_selectを使う!

<%= form_with(model: cart_item, url: cart_item_path(cart_item), method: :patch, local: true) do |f| %>
<%= f.select :amount, options_for_select(1..5, cart_item.amount), class: "form-control" %>
<%= f.submit "変更", class: "btn btn-outline-info mt-2" %>
<% end %>

form_with ヘルパー

form_withヘルパーは、フォームを生成するために使用されます。以下のオプションが含まれています
model: cart_item:フォームがcart_itemオブジェクトに関連付けられていることを示します。このオブジェクトはフォームの入力値を保存するために使用されます。
url: cart_item_path(cart_item):フォームの送信先URLを指定します。ここでは、カートアイテムの更新用のURLです。cart_item_path(cart_item)は、Railsのルーティングヘルパーで特定のカートアイテムのパスを生成します。
local: true:フォームをAJAXではなく通常のHTMLフォームとして送信するように設定します。

問題のところ
<%= f.select :amount, options_for_select(1..5, cart_item.amount), class: "form-control" %>

:amount:選択リストのフィールド名。ここではカートアイテムの数量を表します。
⭐️options_for_select(1..5, cart_item.amount)
→選択リストのオプションを生成します。1..5は選択肢の範囲を示し、cart_item.amountは現在の数量を選択済みとして表示します。
options_for_selectは、第二引数に現在選択されている値を渡すことで、その値がデフォルトで選択されるようにします。
class: "form-control":選択リストにBootstrapのform-controlクラスを適用して、スタイルを整えます。


wrong number of arguments (given 0, expected 1)

cartに入ってからバカみたいに出るこれ。数量系苦手なんだろうな🤔
1、メソッドに対して間違った数の引数が渡されたことを示している。
2、メソッドが引数を必要としているにもかかわらず、引数が渡されていない場合に発生します。
これは理解してるんです。解決方法がわからん。

update controller
@cart_item.update
         ↓
@cart_item.update(cart_item_params)

@cart_item.update(cart_item_params) の (cart_item_params) は、ストロングパラメータを利用してフォームから送信されたデータを安全に取得し、そのデータを使用して @cart_item の属性を更新するための引数です。

合計金額表示

<%= number_with_delimiter(@cart_items.sum(&:subtotal)) %>

カートにすでに登録されてる商品を追加した際、個数が更新されるようにしたい。

完成コード
def create
  # 新しいカートアイテムの作成
  @cart_item = current_customer.cart_items.new(cart_item_params)

  # 既存のカートアイテムの検索
  existing_cart_item = CartItem.find_by(item_id: @cart_item.item_id, customer_id: current_customer.id)

  if existing_cart_item.present?(意味=存在している場合)
    # 既存のカートアイテムが存在する場合、その数量を更新
    existing_cart_item.amount += @cart_item.amount
    existing_cart_item.save
  else
    # 新しいカートアイテムを保存
    @cart_item.save
  end

  # リダイレクト
  redirect_to cart_items_path, notice: 'カートに商品を追加しました。'
end

#分からないところ自分なりに解説していこう

existing_cart_item = CartItem.find_by(item_id: @cart_item.item_id, customer_id: current_customer.id)

#自分なりの解説
具体的には、CartItem モデルから、特定の item_id(商品のID)と customer_id(顧客のID)の組み合わせで既存のカートアイテムを検索している。
例)顧客ID: 1 / 商品ID: 5
現在の顧客(1)が商品ID 5 をカートに追加しようとする場合

existing_cart_item = CartItem.find_by(item_id: 5, customer_id: 1)
cart_item.amount += params[:cart_item][:amount].to_i

自分なりの解説+💟point

フォームから送られたデータはすべて文字列型!!
つまり、フォームから送られたデータを加算などの演算に用いる場合、to_i メソッドを使い文字列型から数値型に変換する必要があるよね!!!

cart_item.update(amount: cart_item.amount)

#自分なりの解説


フラッシュメッセージに関して

controller
def update
     @genre = Genre.find(params[:id])
     if @genre.update(genre_params)
      flash[:notice]="ジャンル名更新しました"
    redirect_to admin_genres_path
     else
      render :edit
     end
    end
view
<div>
  <%= flash[:notice] %>
</div>

で記載したら管理者ログイン後に[Translation missing. Options considered were: - ja.devise.sessions.admin.signed_in - ja.devise.sessions.signed_in]という謎の文が表示されてしまった。。よーわからんけどdeviseのsingn_inの時に出るフラッシュメッセージがジャンル名更新の<%= flash[:notice] %>に反応してもーてる???
となって調べました😶そしたら解決法を知りました!

controller
flash[:genre_update_notice]="ジャンル名更新しました"
view
<div>
  <%= flash[:genre_update_notice] %>
</div>

と、複数の場所でフラッシュメッセージを出す時はclassみたいに指定できる!!!
(絶対:noticeだけだと思ってた😧😧)

その後きちんと表示されました!!!


カートにアイテムがなかったら注文に進めないようにしたい。

[controller]
  def index
    @cart_items = current_customer.cart_items
  end

[view]
<% if @cart_items.empty? %>
 <h4 class ='btn btn-outline-danger'>現在カートに商品はありません。</h4>
<% else %>
 <%= link_to '注文情報入力へ進む', new_order_path, class: 'btn btn-outline-success' %>
<% end %>

Discussion