背景:通过表单传来的参数,我们可以通过 params[:arg_name] 取得其值,但是偶尔需要 merge 一些新的东西,params = {:other_arg => value}.merge(params),此时再用 params[:arg_name] 便无法取得原来的值,后来经过一番折腾,发现如果改为:params = params.merge({:other_arg => value}),然后通过 params[:arg_name] 就可以取得值,对于这个非常诡异的问题,有如下陷阱,各位不要再掉进去咯
原来 Rails 再帮我们处理参数的时候,会将 params 转换为 Object::HashWithIndifferentAccess 这样的类型,而这一个类型对于 key 是既可以用 string 也可以用 symbol 的,而这一类型的实例再 merge 一个 hash 对象时,也同样会转换成 Object::HashWithIndifferentAccess 类型。
相反的,我们的第一种写法,{:other_arg => value}.merge(params),这里的{:other_arg => xxx}本身是一个 ruby 的 hash 对象,不是 Object::HashWithIndifferentAccess 的类型,所以当它再 merge 一个 Object::HashWithIndifferentAccess < Hash 对象时,它只能转型成 ruby 的 hash 对象,而对于 ruby 的 hash 对象,大家都知道 key 是区分 string 和 symbol 的,因此出现了上述问题