保华的Rails学习笔记

无主群组的另类解决方法(不用delete_all删除)

当一个table表有新增加栏位后,如果之前有历史数据,当再次展现这些数据时,就会报错,因为历史数据在新增加的栏位上,它的值是nil

例如在我们的rails101教材中,当给groups增加user_id栏位后,就出现了无主群组的报错,如下图


教材中,给我们的解决方案是

Group.delete_all

简单直接,对于刚开始做rails101的朋友来说,可以快速解除bug,顺利跳过这个坑

可是如果我们rails101做了好多遍,而且是在product环境中、groups表里已经有了很多数据(甚至是重要的数据),我们是否能保留这些数据、而且解决掉bug呢?答案当然是肯定的,下边我提供两种解决方案供参考

首先,我们可以先证实这些groups确实是无主的,办法是先进入rails console中,输入Group.all,如果执行结果中所有group的user_id栏位值都是nil,那就可以证实确实是无主群组问题引起的

第一种解决方案,其实也很简单,既然这些group的user_id值都为nil,那么我们给这些group的user_id批量赋个值就可以了,方法是先进入rails console中,然后输入

Group.update_all(user_id:1) 

如果没有user_id为1的用户,上边的代码可以修改为:

Group.update_all(user_id:User.first.id)


这样所有的group的user_id都为1了,group从无主变有有主,再刷新浏览器,问题就解决了

问题虽然解决了,可是所有group的user_id都为1了,不太符合真实环境下的数据,真实环境里边的数据,这里的user应该是分散的

为了实现user_id有一定的随机性,我们可以这样做

进入rails c环境中,执行下边的代码段

Group.all.each do |group|
   group.user_id = User.ids.sample
   group.save
end

注意:在rails c中执行上边的命令行时,可以一行一行输入
也可以直接复制我的这4行代码,到rails c中执行

其中,User.ids执行的结果是所有user的user_id所组成的数组,例如[1,2]
User.ids.sample的执行结果为user中id的随机值

得到的结果如下图


group的user有一定的离散性了,更符合真实环境下的数据

总之,解决无主群组的问题时,建议首先要确认是否真的是group无主问题,可大多数同学都是靠猜的(个人建议rails101做了好多遍的同学还是确认下,不但要知道解决方案,还要知道问题发生的根源),确认以后,给这些group的user_id赋值就可以了,无论是批量给group都赋同一个值(例如第一种方法),还是给每一个group随机赋个值(第二种方法),都是可以解决的