TL;DR
とある設定値(Hash)をDBから取得した値に更新したかった。
ところが hash.merge(Model.attributes)
すると String型とSymbol型のキーで重複した値ができてしまった。
これをなんとかしたくていろいろググってしまったが非常にシンプルな解決策があったのだけどそこにたどり着くまでにそこそこ時間がかかってしまったという訓戒。
結論:
attributesで取得したHashに対してsymbolize_keysすればよい。
pry(main)> {"name" => 'hoge fuga', "age" => 17}.symbolize_keys
=> {:name=>"hoge fuga", :age=>17}
ActiveRecordからHashにする方法はいくつか出てきたのだけどそのHashがString型で少し困る事態が発生してしまった。
可能ならキーはSymbol型が嬉しいのだけどattributes
が返すHashはString型だったのでうまく意図したデータになってくれなかった。
with_indifferent_access
でキーがString型でもSymbol型でもどっちでもOKになるのだけど出来れば厳密にしたかったためSymbol型に変換した状態でマージをするためにはどうすればいいのだろうか?と考えていた。
当初はHashの中身をループさせて変換されたものを再代入すればいいかと思っていたのだがそんな泥臭い方法しないといけないのだろうか?と気になって調べ直したところ、↓のエントリにたどり着き自分がやりたかったことがシュッと実現できる運びになってHappy!という感じです。
ちなみに泥臭い感じのコードは↓と全く同じでした。
Hashのキーを文字列からシンボルに変換する
HashのキーがString型もSymbol型も許容するのはいいのだけど内部的にはSymbol型で統一してほしいという気持ちがある。
とはいえそれをしてしまうとString型とSymbol型で異なるキーだと判断しているいまのHashの振る舞いが変わってしまうので難しいんだろうなーと思うとなかなかつらみ。