Ruby on Railsでupdateの限定に自前の主キーを指定する
本日二度目の投稿。つーか書いとかないと気が立ってしょうがない。
Ruby on Railsにはupdate系列のメソッドが色々ある。
update、update_attributes、update_all・・・。
ありすぎて、どれを使えばいいかわからなくなるが、俺がやりたかったこととしては、「Railsのデフォルトのid付番を使用していない自前の主キーであるuser_idでデータを限定してそれをupdateすること。」
要はSQLのUPDATEで言うところの
UPDATE users SET users.lname = 'キャトル', users.fname = 'ミュート' WHERE users.user_id = 'cattlemute';
っていうやつがやりたかった。
(SQLの例文ね。実際はSQLインジェクションの問題があるからこんな平文にはならないけど。)
これをやるためにupdate系列のメソッドをいろいろ試してことごとく失敗した挙句、最終的には目的のコードが実行できたという話。
結論から言うと、これを行うためには数あるupdate系列のメソッドでも「update_all」を使用しなければいけないみたいだ。
updateはRailsのデフォルトのidをキーにして更新するものだから論外だし、update_attributesは限定条件を付けるためのfind_byだとかwhereだとかを使うとmodel関係のエラーが発生する。
なので必死をこいてこんなことや、
user_data = User.find_by(:user_id => 【user_id】) user_data.update_attributes( :lname => 【ポストしてくるlname】, :fname => 【ポストしてくるfname】 )
リファレンス通りにこんなことしても、
user_data.update_attributes = { :lname = 【ポストしてくるlname】, :fname = 【ポストしてくるfname】 }
はい、問答無用でエラーします。
リファレンスサイトさんの場合、前に書いたforeign_key事件でも「しかしてここに書いてある情報ってあんまり信用できないのかな」と思っていたのだが今回の件で確信した。
このリファレンスサイトさんは色んな所がプッツンしてやがる。
自分の求めているUPDATE文と同じことをやりたい人っているもんだと思って他サイトさんを調べてみた。
次に調べるべきヒントはちゃんと出てくるけど肝心なところが書いてない(´・ω・`)
彼ら彼女らはきっと俺みたいな凡人ではなく「Rails使うなら当然わかってるよね^^」といった天才的観念から書いているのかもしれない・・・モンハンのような初見さんお断り的な冷たい空気をどことなく感じた。(飽くまで感じただけだからね?)
まぁそんな空気の中にもバクテリアのサイズで優しさは存在するけど。要はツンデレ(死語)だ。
ヒント書いてあるだけでも御の字です。
でも、本当に初心者にやさしくないフレームワークだ。
で、まぁ単純に調べるだけじゃ絶対もう無理だと判断して、結局いつものように自分で色々試行錯誤した。
求める実行結果を得るためには、以下のようなコードを書かなければいけないということを、小一時間悩んで出した。
User.where(:user_id => 【user_id】).update_all( :lname => 【ポストしてくるlname】, :fname => 【ポストしてくるfname】 )
これでやっと冒頭で書いたようなSQLのUPDATEの結果を得ることができた。
まぁ、たったこれだけのコードなのになぁ。
というかプライマリキー関係でトラブルよくあるな、これ・・・。
Railsではテーブルの管理の面でidをプライマリキーに指定しない(してはいけない)ような要件でも、絶対にidをプライマリキーにしなきゃならんのかねぇ?(皮肉)