LoginSignup
0
0

More than 3 years have passed since last update.

form_with url指定(ネストしてるとき)

Posted at

初投稿です。よろしくお願いします。

スクールでECサイトのチーム開発をしているときに出た不明点の備忘録です。

ネストしてるときのform_with url指定

form_withのurlオプションでidを2つ指定すると正常に値が渡されて動くようです。
今回はorderとorder_itemが1対多の関係になっています。
また、admin_order_order_item_pathはorder_itemをupdateする際の名前付きルートです。

orders_controller.rb
def show
    @order = Order.find(params[:id])
    @order_items = OrderItem.all.includes(:item)
    @order_item = OrderItem.find(params[:id])
end
order/show.html.erb

<% @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を指定する必要があります。

order_items_controller.rb
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を更新したい場合)

orders_controller.rb
def show
    @order = Order.find(params[:id])
    @order_items = OrderItem.all.includes(:item)
    @order_item = OrderItem.find(params[:id])
end
order/show.html.erb

<% @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)としたら動いてしまいました。)

order_items_controller.rb
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分で解決しました。

まとめ

調べるまでもなく基本事項だったのかもしれませんが、勉強になりました。

0
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
0
0