RubyのHash#with_indifferent_accessは便利

公開日: 2016年11月13日GitHub

課題

フォームからの入力に対してデフォルト値を利用したいとき、 Hash#mergeを利用することで簡単にデフォルト値をベースに、入力を上書きすることが出来ます。

1def default_hash
2 { 'name' => '太郎' }
3end
4user = User.new default_hash.merge(user_params)
5

ただし注意点。 railsのparamsメソッド等で返るHashは、keyがStringであってもSymbolであっても区別しませんが rubyのHashはkeyがStringである場合とSymbolであることを区別します。 http://apidock.com/rails/ActiveSupport/HashWithIndifferentAccess

なので、もしdefault_hashのkeyがStringである場合には、上書きされない、なんてことが起きます。 基本的にHashのkeyはSymbolにしたほうがいいのですが、やむを得ずロケット記法でStringをkeyにするとこんなかんじに。

1user_params
2=> { name: '花子' }
3default_hash.merge(user_params)
4=>
5{ 'name' => '太郎', :name => '花子' }
6

解決策

mergeする用のデフォルト値を格納しているhashは

1def default_hash
2 { 'name' => '太郎' }.with_indifferent_access
3end
4

として、with_indifferent_accessしましょう。

This site uses Google Analytics.
source code