当我们把现有的应用升级到最新 Rails 版本 5 时,版本的更新将会将会对我们的程序有很多不同的影响。为了保持我们原有的快速开发与版本更新速度,我将分享一系列的文章为你的 Rails 版本更新做准备。
在此次版本更新中,一个比较大的变化就是 ActionController::Parameters 的运作方式。ActionController::Parameters 是通过 params 来严格控制传进来 Controller 的参数,而在 Rails 5 新版本之前,params 一直是返回 Hash 函数,而现在它将返回对象。
注意:这并不影响在 params hash 里的键值访问,例如 params[:id]。通过以下链接,我们可以看到新版本代码的变化:https://github.com/rails/rails/pull/20868
我们可以通过在 params 上加上#to_h 从而实现访问在对象里面的参数,请参考如下代码:
如果 params 没有明确允许(permitted),则 params 只会返回一个包含允许的参数的 Hash,如果所有参数都没有明确允许,params 则只会返回一个空的 hash({})。如果你使用了未允许的 params,上述描述情况,这将会发生在运行#symbolize_keys 或者#slice 时。如果你正在访问没被保存到 model 或者 database 的 params,那么你可能没有明确允许那些参数返回。
我们仔细观察 ActionController::Parameters 的#to_h 函数会发现,在将其转化为 Hash 前,会先检查 parameters 是否被允许。 让我们看一个后面用到的 slicing params 例子。下面是我们过去使用的 slice params 代码: 返回的结果是:
但是现在会返回一个 ActionController::Parameters 对象,而不是 Hash。
在这里调用 #to_h 将会返回一个空的 hash,因为 param_1 和 param_2 都是不被允许的。
从 ActionController::Parameters 中访问 params,你先要允许这些参数,然后在对象中调用#to_h。下面是之前调用 slice 返回的结果:
另一种避免返回空 hash 的方法是,使用 #to_unsafe_hash 函数,前提是你明确这些参数不是用户提供并且没有安全风险的情况下:
在默认情况下,controller 和 action 的参数是允许返回的。如果你需要返回 controller 和 action 以外的参数,你可以设置在 application.rb 的配置,改为总是允许其他参数返回。注意:这将会返回 string keys 的 hash,而不是 symbol keys。
配置选择: 调用 slice:
如果你不确定是否有时间去升级 Rails 5,我会建议你提前为你的 Controller 代码准备好测试代码,尝试访问 params,这样当你升级的时候你就可以通过运行你的测试代码发现那些需要修改的 params。