LoginSignup
0
0

More than 3 years have passed since last update.

複数のレコードを一括処理

Posted at

一括でレコードをアレコレするやり方。なお割と力技。
それぞれやりたい事は以下。

①カートを空にする =Userに紐づくCartレコードを全削除
②カートに入ってる商品を注文する =複数のCartレコードを使って複数のOrderProductレコードを作成する。
③注文情報と注文商品情報をまとめて変更する =親要素と子要素を一括でupdateをかける

前提ーー
Cartモデル、OrderProductモデルには以下のカラムがある
・product_name
・quantity
・price
・order_id(OrderProductのみ)
・status(OrderProductのみ)
Orderモデル
・user_id
・status

User<Cart,Order
Order<OrderProduct が1対他の関係。

①カートを空にする

delete_allメソッドを使う。これを使うとUserに紐づいたCartレコードを全て削除できる。
似たようなものでDestroy_allがあるけどこちらはUserに紐づいた全てのレコードが削除されるらしい。つまりこの前提だとOrderレコードまで消えるっぽい。
actionはdestroyを個別削除に使っていたので新しく作成する。

config/routes.rb
delete 'public/carts' => "public/carts#delete_all"
carts_controller.rb
def delete_all
 @user = current_user
 @user.carts.delete_all
end
Carts/index.html.erb
<%= link_to "カートを空にする", public_carts_path, method: :delete %>

②カートに入ってる商品を注文する

ここでやりたい挙動は
1、Orderレコードを新しく作成
2、そのIDを使ってOrderProductを作成

controller
def create
 @user = current_user

 @order = Order.new
 @order.user_id = current_user.id
 @order.save!

 @user.carts.each do |cart|
  order_product = OrderProduct.new
  order_product.order_id = @order.id
  order_product.quantity = cart.quantity
  order_product.product_name = cart.product_name
  order_product.total = cart.product.price
  order_product.save
 end
end

もっと大量のデータを扱う場合は別のやり方があると思う。
.eachで回すのはナンセンスだけどやり方調べる時間がなかった。

③注文情報と注文商品情報をまとめて変更する

これが一番難しかった。何なら今でもいまいち理解できてない。

order_controller
def update
 @order = Order.find(params[:id])
 @order.update(order_params)
end

private
def order_params
 params.require(:order).permit(:user_id,:status, order_products_attributes: [:id, :status, :_destroy])
end
models/order.rb
accepts_nested_attributes_for :order_products
<%= form_for [@order] do |f| %>
 <%= f.select :status, ['入金待ち', '入金確認', '製作中', '発送準備中', '発送済み'], {}, class: "dropdown" %>
 <%= f.fields_for :order_products do |order_product| %>            
   <%= order_product.select  :status, ['着手不可', '製作待ち', '製作中', '製作完了'] %>   
  <% end %>
  <%= f.submit "更新" %>
<% end %>

order_products_attributes: [:id, :status, :_destroy]
まず一番にcontrollerのこいつ。order_paramsに入りこんでるこいつ。attributesを使うならこれとモデルへの記述が必要でidと_destroyは形式として突っ込むらしい。何故かはよくわからない。

それからfields_for。これをform_forの中にとりあえず入れると、そこで子要素を編集できる。fields_forをかけると子要素のレコードを繰り返し持ってこれるので.eachはいらない。ただし

タグで:product_nameなんかを表示させる為に.eachも併用すると途端にテーブルが崩壊する。そういう場合はもうテーブルを分ける。入力のテーブルと商品名とかを表示させるテーブルをいい感じにくっつける。

submitはform_forの中且つfields_forの外。

これでいける。

え、同じ値を全レコードのカラムにぶち込みたい?
.eachで .カラム = "入れたい値" を回せばいいんじゃないかな。
createならsaveする前に入れてさ。

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