0
0

More than 3 years have passed since last update.

Railsでupdate_allとストロングパラメーターを併用した際のエラー対処

Last updated at Posted at 2021-02-22

状況

railsのupdate_allメソッドとストロングパラメーターを併用して、SQLの発行回数を減らしてデータを一括更新したい。

パラメーター

Parameters: {"update_ids"=>["1", "2", "3"], "group_id"=>"2"}

update_idsで取得した複数のアイテムの属するグループIDを一括で変更したい。

該当コード

items_controller.rb
def update
  ids = params[:update_ids]
  Items.where(id: ids).update_all(update_params)
end

private

def update_params
  params.permit(:group_id)
end

もちろん今回のような単純なケースだとストロングパラメーターを使用する必要はなく、

items_controller.rb
def update
  ids = params[:update_ids]
  Items.where(id: ids).update_all(group_id: params[:group_id])
end

と書けば目的は達成できますが、今後更新項目が増えていった際の想定の元にストロングパラメーターの使用を試みたという前提です。

エラーメッセージ

TypeError (no implicit conversion of Hash into String)

検証:updateで書き直してみる

SQLの発行回数を減らしてデータを一括更新とは趣旨がずれてしまいますが、

items_controller.rb
def update
  ids = params[:update_ids]
  Items.where(id: ids).update(update_params)
end

とすると先程のエラーは解消されました。
ということはupdate_all独特のエラー・・・?

エラー解決

items_controller.rb
def update
  ids = params[:update_ids]
  Items.where(id: ids).update(update_params.to_hash)
end

という具合にupdate_params.to_hash.to_hashと型指定をした所、処理が通り、SQLも一行で無事値を更新することが出来ました。
調べる限り同様の対処方法で解決しているケースも見受けられました。

update_allとストロングパラメーターを併用する場合、明示的に型変換をしないとエラーが出るような仕様になっているのでしょうか。
一先ず解決はしましたが、他にも良い方法等ありましたらご教示いただければ幸いです!

参考

https://teratail.com/questions/285505
https://takuya-1st.hatenablog.jp/entry/2016/08/25/041804
https://stackoverflow.com/questions/27372255/ruby-typeerror-no-implicit-conversion-of-hash-into-string

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