rails中params[:id]与params["id"]分析
写这个帖子的缘由是因为在页面参数传到rails的controller时用params[:]和params[""]都可以取到值:
[1] pry(#<BooksController>)> params => {"action"=>"show", "controller"=>"books", "id"=>"382"} [2] pry(#<BooksController>)> params["id"] => "382" [3] pry(#<BooksController>)> params[:id] => "382"
由上边代码可知params是一个Hash.在正常的Hash下根据key取值只能用 :或者 ""一种取。
在irb调试代码:
yuyudemac-mini:~ yuyu$ irb 2.0.0-p451 :001 > a = {"id" => 1} => {"id"=>1} 2.0.0-p451 :002 > a["id"] => 1 2.0.0-p451 :003 > a[:id] => nil
为什么在rails中params[:id]和params["id"]都能取到值呢?
其中的原因时因为
2.0.0-p451 :004 > a.class => Hash
irb下的a的类时Hash
[5] pry(#<BooksController>)> params.class => ActiveSupport::HashWithIndifferentAccess
而rails下的params类却是ActiveSupport::HashWithIndifferentAccess
HashWithIndifferentAccess是 Hash的子类,其中覆盖了rails源码中的default 方法,Hash当找不到 hash 的 key 时 会去寻找default值,去执行 default 方法 。
源码中的default方法:
def default(key = nil) if key.is_a?(Symbol) && include?(key = key.to_s) self[key] else super end end
也就是说,在params中调用params[:id]时,满足key.is_a?(Symbol) && include?(key = key.to_s)就去执行default方法,使:id和"id"对应一个value,这时再调用params["id"],params["id"] 等于params[:id]的值。
关于default方法参考地址:http://lukaszwrobel.pl/blog/ruby-hash-default-value