我如何编写一个Rails查询来查找所有以各种格式保存的电话号码



我使用的是Rails 5.2.0

我正试图编写一个查询来查找基于用户输入的电话号码。但是,保存在数据库中的电话号码格式各不相同(例如(123)-456-7890、+1(123)-456-7890、+1 123456789等)。是否有任何方法我可以格式化保存在我的数据库中的记录在这个查询?我想过在表中添加第二列,即formatted_telephone,但是我有成千上万条记录。我可以在User控制器中添加一个方法来更新这些记录吗?

到目前为止我写的是:

User.where("REGEXP_REPLACE(telephone, '[^[:digit:]]', '') ~* ?", "%#{input}%")

现在它仍然只返回这种格式的电话号码:1234567890。

我的思路对吗?或者在查询时不能设置列的格式?

通常使用where子句和regexp,我们会要求诸如"找到与此regexp匹配的所有内容"之类的内容。但是你要求数据库提供一个与"12035551212"匹配的电话号码。并且希望where子句在搜索以匹配它时对表中的每个电话号码应用regexp。我猜你可以尝试这样做(这可以简化,但我把它分解,使其更容易遵循):

my_phone = '12035551212'
phone_arr = my_phone.split('') 
#=> ["1", "2", "0", "3", "5", "5", "5", "1", "2", "1", "2"]
regx = '^D?' + phone_arr[0] + '?' + 'D*' + phone_arr[1..-1].join('D*') + '$'
#=> '^D?1?D*2D*0D*3D*5D*5D*5D*1D*2D*1D*2$'

现在你有一个只匹配你的电话号码而不管格式的regexp。现在你可以试试:

User.where('phone_number ~* ?', regx)

这应该要求Postgres根据您正在搜索的电话号码匹配您的特定regexp。这应该能满足你的需求。但是我会考虑重构它。

从长远来看,我会标准化数据库中的所有数字。您可以向Users添加一个phone_number_e164列,并使用regexp将每个列转换为E164格式。然后删除旧的电话号码列,并将新列重命名为phone_number。您还需要添加代码来标准化进入数据库的任何新数字。

作为一种权宜之计,你也可以创建一个Postgres视图来获取User记录,并对电话号码应用regexp将其转换为E164格式,并访问该视图而不是User表。

最新更新