以下是代码:
def autocomplete
if(params[:terms])
key = params[:terms]
customers = Customer.where(:$or => [
{:first_name => Regexp.new(/^#{key}/i)},
{:last_name => Regexp.new(/^#{key}/i)},
{:email => Regexp.new(/^#{key}/i)},
#{:phone => Regexp.new(/^#{key}[d+]/i)},
{:phone => Regexp.new(/^#{key.gsub(/\D+/,'')}/)},
{:zip_code => key.to_i },
{:street1 => Regexp.new(/#{key}/i)},
{:street2 => Regexp.new(/#{key}/i)}
]
)
Tin Man建议的gsub方法让我几乎到了那里 - 只有在我的数据库中的:phone字段中搜索时才会从搜索字符串中删除任何非Digit字符。
最后一个问题是:数据库中的:phone字段可能实际上有非Digit(我想让用户输入他们想要的电话号码),所以我需要暂时忽略破折号搜索(在Mongo中使用find())
不确定我是否应该在自动完成功能中执行此级别,或者我是否应该在autocomplete.js模块中执行此操作...
摘要 - 我想:phone.gsub(/ \ D + /,'')但gsub仅适用于字符串,而不是像这样的引用。
答案 0 :(得分:2)
我看到的一些事情:
Regexp.new(/^#{key}[d+]/i)}
[\d+]
是无稽之谈。放下周围的[]
。
有关:
{:zip_code => key.to_i },
不要将邮政编码转换为整数。一些邮政编码是连字符,这将删除尾随值。此外,除非您打算对值执行数学运算,否则请将其保留为字符串。
什么是$or
?使用全局通常是代码嗅觉的标志。在Ruby中使用一个的原因很少,而且我的代码中没有一个很好用,并且通常可以使用常量轻松地重构它。
我认为你实际上通过指出ZIP的key.to_i来回答我的问题 - 这实际上正是我想要用电话号码做的事情 - 去掉所有的破折号,空格,括号等等。我打算给那个一试。
不,不,不,不。 to_i
不会做你想做的事。 '0-1'.to_i => 0
和'0.1'.to_i => 0
。相反,您想要使用gsub
从字符串中去掉所有非数字字符,然后就完成了:
'0.1'.gsub(/\D+/, '')
=> "01"
'123-456-7890'.gsub(/\D+/, '')
=> "1234567890"
'(123) 456 7890'.gsub(/\D+/, '')
=> "1234567890"
'0.1'.gsub(/\D+/, '').to_i
=> 1
注意上面to_i
收到"01"
时发生的事情,删除了前导零,因为它对于Fixnum的表示没有意义。你可以强制它使用字符串格式显示,但为什么?电话号码不是数字值,它是一个字符串值,即使它是一堆数字。我们从不需要对它们或任何数学进行添加,因此将它转换为整数是没有意义的。将其保留为一串数字。