初投稿です。よろしくお願いします。
スクールでECサイトのチーム開発をしているときに出た不明点の備忘録です。
ネストしてるときのform_with url指定
form_withのurlオプションでidを2つ指定すると正常に値が渡されて動くようです。
今回はorderとorder_itemが1対多の関係になっています。
また、admin_order_order_item_pathはorder_itemをupdateする際の名前付きルートです。
def show
@order = Order.find(params[:id])
@order_items = OrderItem.all.includes(:item)
@order_item = OrderItem.find(params[:id])
end
<% @order_items.each do |order_item| %>
<%= form_with(model:[order_item], url: admin_order_order_item_path(order_id: @order.id, id: order_item.id)) do |f| %>
<%= f.select :production_status, [["着手不可","着手不可"],["製作待ち","製作待ち"],["製作中","製作中"],["製作完了","製作完了"]] %>
</td>
<td><%= f.submit "更新" %></td>
<% end %>
↑ブラウザに表示されるurlがorder/:order_id/order_item/:id のようになるため、
url: admin_order_order_item_path(order_id: @order.id, id: order_item.id)というふうに前から順番にidを指定する必要があります。
class Admin::OrderItemsController < ApplicationController
def update
order_item = OrderItem.find(params[:id])
order_item.update(order_item_params)
redirect_to admin_order_path(order_item.order_id)
end
private
def order_item_params
params.require(:order_item).permit(:production_status)
end
end
form_withがeach文の中の@order_itemsでorder_itemのidを持ってきているので、そのidをorder_item = OrderItem.find(params[:id])の(params[:id])に入れてOrderItemモデル内を検索し、該当レコードをupdateして完了。
余談
ちなみに、メンターさんに教えてもらう前までは、以下のように記述して、なぜか思った通りに動いてはいるもののターミナルに出ているパラメータの数値がなんかおかしい・・・という状態になっていました。
(例えばorder_id:1の中にあるorder_item_id:5を更新したい場合)
def show
@order = Order.find(params[:id])
@order_items = OrderItem.all.includes(:item)
@order_item = OrderItem.find(params[:id])
end
<% @order_items.each do |order_item| %>
<%= form_with(model:[order_item], url: admin_order_order_item_path(order_item.id)) do |f| %>
<%= f.select :production_status, [["着手不可","着手不可"],["製作待ち","製作待ち"],["製作中","製作中"],["製作完了","製作完了"]] %>
</td>
<td><%= f.submit "更新" %></td>
<% end %>
admin_order_order_item_path(order_item.id)の部分では、
order_item_idの(5)が入っていますが、本来であれば、順序的にはorder_idが入らないといけないので、それが次の
.find(params[:order_id])の部分に入ります。(当初.find(params[:id]としていましたが、idが見つからないというエラーが出てしまったため、いろいろ試して苦し紛れで[:order_id)としたら動いてしまいました。)
class Admin::OrderItemsController < ApplicationController
def update
order_item = OrderItem.find(params[:order_id])
order_item.update(order_item_params)
redirect_to admin_order_path(order_item.order_id)
end
private
def order_item_params
params.require(:order_item).permit(:production_status)
end
end
order_item = OrderItem.find(params[:order_id])の[:order_id]に(5)が入り、OrderItemモデルの中の5番目のレコードを探して order_itemに入れてupdateしています。
これでこれで思惑通り5番目のレコードが更新されました。が、
ターミナルを見ると、
Parameters: {(略}, "commit"=>"更新", "order_id"=>"5", "id"=>"1"}
となっていて、
(あれ、"order_id"=>"1", "(order_item_)id"=>"5"が正しいよな・・・ なんで・・・?)
と思って調べても出てこず、メンターさんに教えていただき10分で解決しました。
まとめ
調べるまでもなく基本事項だったのかもしれませんが、勉強になりました。