Rails Rails MySQL String too long cause error

geekjj · 2016年05月31日 · 最后由 tesla_lee 回复于 2016年06月03日 · 3105 次阅读

环境

开发

  • 数据库:Sqlite3

线上

  • 数据库:MySQL

问题

使用 String 类型存储名字的字符串,当前段输入值过长时会导致 MySQL 出错,应用出现 FATAL 并报错“ActiveRecord::StatementInvalid (Mysql2::Error: Data too long for column。。。” 。

这个问题可以在前段或者后端 rails 代码添加对 name 等字段的长度限制,但是应用中这种字段比较多,如果每一个都添加一个限制的话比较麻烦。

求教有没有什么方法可以让 ActiveRecord 不要抛异常,而是 rollback,并在 Errors 里面添加相关提示?

补充:由于开发环境和线上环境数据库不同,经常在本地开发环境一切 OK,但是线上测试无法通过的问题,比如:MySQL 和 Sqlite3 在检测字符串唯一性是对大小写是否敏感的处理方式就不一样。想问下大神,除了开发和线上使用同一数据库,有没有什么方法可以解决这种问题?

好奇葩,开发使用的数据库和线上数据库不一致。把 string 改为 text 类型简单解决,你还需要找什么好方法呢?

#1 楼 @pathbox 项目的历史遗留问题吧,rails 自带的 sqlite3 一直没动,线上使用了 mysql 这样。对于简单的信息比如姓名、电话地址啥的直接都用 text,这么合适吗?

#2 楼 @geekjj 不合适。你可以先查出是具体哪个字段报了 过长情况。如果是 name 这样的字段都报的话,还是想法子都用 mysql 吧

那为什么不在 Model 里直接加一个 validate?

#4 楼 @tesla_lee 在 model 里面加 validate 是可行的,但是一个比较麻烦的问题是,你几乎要给应用中所有 model 的几乎所有字段加上这个 validation,这个工作量令人恶心。不过刚好看到了一个 gem 自动帮我们做了这件事情,觉得很棒,大家可以看一下http://codecolossus.com/blog/2011/01/01/validates-lengths-from-database.html#.V1ARLlWqpBc

#3 楼 @pathbox 都用了 mysql,但是这个问题依然存在。对于数据库中的类型,比如 String 一类的 varchar 等等,在数据库一侧是有长度限制的,但是 ActiveRecord 并没有验证长度直接 commit 到数据库,然后数据库报错。这种问题目前还没有找到比较好的方法,比较可行的方法就是在 Model 中对于每一个字段进行数据库长度验证,而这个繁琐的工作最好是有一个通用库来统一处理,目前找到了https://github.com/rubiety/validates_lengths_from_database

string 数据库长度不是 255 么?你有超过 255 的长度 用 text。像 name 这样的字段 实际应用中不会超过 255 吧。。。直接限制长度输入。超过限制长度直接不保存,给提示。这不是麻烦不麻烦的事情。使用 那个 gem 不是一样 需要在需要的 model 里 写 "validates_lengths_from_database :limit => {:string => 255, :text => 4092}" 这样的长度限制么?不过 看了下 这个 gem 使用还是挺方便的。举个例子:如果 content 字段已经用了 text,limit: 65535. 用这个 gem 设置 :text => 4092,数据库中的 实际限制长度还是 65535,不是 4092 吧?只是在存入数据库之前又做了验证判断,而实际数据库的 text 类型字段属性是没改的

我懂你的意思了,我理解错了#5 楼 @geekjj

需要 登录 后方可回复, 如果你还没有账号请 注册新账号