【问题标题】:Restrict parameter in Rails route to INT(11) range将 Rails 路由中的参数限制为 INT(11) 范围
【发布时间】:2015-11-04 11:11:50
【问题描述】:

问题:当 API 客户端向我的 Rails 4.2.4 应用程序发送参数超过最大值 2147483647 的请求时,我不断收到这种异常:

RangeError: 1446629302683 超出范围 ActiveRecord::Type::Integer 限制为 4

数据库是 MySQL,列的数字类型是 INT(11),所以我想直接在路由中限制接受参数的范围,例如

get 'movies/:id(.:format)' => 'movies#show', constraints: { id: /.../ }

如何在这里将 4 个字节的范围定义为正则表达式?或者有更聪明的方法吗?

【问题讨论】:

  • 为什么要使用正则表达式?您确切知道限制,因此只需检查参数是否低于限制。
  • 如何在路由指令中表达这样的条件?

标签: mysql ruby-on-rails regex ruby-on-rails-4


【解决方案1】:

我建议您使用 8 字节整数 (bigint) 而不是 4 字节整数,而不是限制路由中的 id。

使用(limit: 8 选项)在您的迁移文件中以这种方式声明:

add_column :movies, :id, :integer, limit: 8

这将为您的id 提供一个上限9223372036854775807,其中 4 字节整数的限制是2147483647

有关bigint in Rails migrations, and what :limit means for column migrations 的更多信息,请参阅此帖子。

但是,如果您真的想使用正则表达式将 id 限制为 bigint 限制 (9223372036854775807),那么这里是正则表达式:

\b([1-9][0-9]{0,17}|[1-8][0-9]{18}|9([01][0-9]{17}|2([01][0-9]{16}|2([0-2][0-9]{15}|3([0-2][0-9]{14}|3([0-6][0-9]{13}|7([01][0-9]{12}|20([0-2][0-9]{10}|3([0-5][0-9]{9}|6([0-7][0-9]{8}|8([0-4][0-9]{7}|5([0-3][0-9]{6}|4([0-6][0-9]{5}|7([0-6][0-9]{4}|7([0-4][0-9]{3}|5([0-7][0-9]{2}|80[0-7]))))))))))))))))\b

这个正则表达式由Utility Mill 生成,我在rubular 上对其进行了测试。

因此,使用上面的正则表达式,您的路线变为:

get 'movies/:id(.:format)' => 'movies#show', constraints: { id: /\b([1-9][0-9]{0,17}|[1-8][0-9]{18}|9([01][0-9]{17}|2([01][0-9]{16}|2([0-2][0-9]{15}|3([0-2][0-9]{14}|3([0-6][0-9]{13}|7([01][0-9]{12}|20([0-2][0-9]{10}|3([0-5][0-9]{9}|6([0-7][0-9]{8}|8([0-4][0-9]{7}|5([0-3][0-9]{6}|4([0-6][0-9]{5}|7([0-6][0-9]{4}|7([0-4][0-9]{3}|5([0-7][0-9]{2}|80[0-7]))))))))))))))))\b
/ }

【讨论】:

  • 如果 API 客户端发送的(无效)ID 大于 9223372036854775807 的请求,仍然会抛出异常 ...
  • @Boris 查看我更新的答案,我向您展示了如何使用正则表达式来做到这一点。让我知道这是否有帮助或您有任何其他问题。
  • 谢谢,将我指向 regex_for_range 生成器是解决方案。在我的情况下,路线变为:get 'movies/:id(.:format)' => 'movies#show', constraints: { id: /1[-9][-9][-9][-9][-9][-9][-9][-9][-9]|20[0-9]{8}|21[0-3][0-9]{7}|214[0-6][0-9]{6}|2147[0-3][0-9]{5}|21474[0-7][0-9]{4}|214748[0-2][0-9]{3}|2147483[0-5][0-9]{2}|21474836[0-3][0-9]|214748364[0-7]|[2-9]|[1-9][0-9]|[1-9][0-9]{2}|[1-9][0-9]{3}|[1-9][0-9]{4}|[1-9][0-9]{5}|[1-9][0-9]{6}|[1-9][0-9]{7}|[1-9][0-9]{8}/ }
  • 不客气。 Gald 我可以帮你解决你的问题。
  • 认为我用于上述表达式的Regex range generator 有问题! A Python script 产生了一个看起来有效但太长的表达式,无法在此处发布。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
相关资源
最近更新 更多