2011-06-11 76 views
1

我是Rails验证的总新手,虽然我看到一些相关问题,但我无法确定如何将它们扩展到我的情况。rails 3验证邮件地址的逗号分隔列表

我需要允许用户设置他们的帐户,以输入N(系统常量,如10)可选电子邮件地址。

,因此用户会输入到文本字段中的数据可能看起来像

[email protected] 

[email protected], [email protected],[email protected] , [email protected] 

(注意不一致的使用空间之前或逗号之后,典型的真实用户的东西)

目前在我的模型我处理单可选的电子邮件,并使用正则表达式:

validates :alert_email, 
    :allow_blank => true, 
    :length => {:minimum => 3, :maximum => 254}, 
    :format => {:with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i} 

有可能是某种超级正则表达式,我可以用...替换我的,如果任何人都可以帮忙的话,那将是很好的。然而,为了可读性(并且因为性能是无关紧要的,因为这是每个用户执行一次),我想我应该以某种方式将验证移动到一种方法,蛮力分析出来并一次运行正则表达式。

PS我还想要我的验证例程来“修正”空格/逗号的事情,所以它总是在列表中的项目之间的逗号空间,并且已将该固定版本保存起来。我猜我做了一些before_xxxxx方法?

回答

3

您可以使用Ruby split方法将您的电子邮件列表分隔成一个数组,并使用联接方法将其保存为通用格式。

before_validation do 
    emails = self.emails.split(/\s+,\s+/) 

    emails.each do |email| 
    self.errors.add(:emails, "invalid email") unless value=~ /([^\s]+)@([^\s]+)/ 
    end 

    self.emails = emails.join(",") 
end 
+0

像这样解析模型是引入错误的绝对方法。例如。当该字段已经是一个数组时,您的示例会中断。 – jdeseno 2011-06-12 04:47:20

+0

我怀疑jdeseno的评论在技术上是正确的,但是,在我特别简单的应用程序和UI情况下,它看起来像这可能是一个相对新手如自己最简单和最简单的路线。 – jpwynn 2011-06-12 08:20:01

+0

emails = self.emails.strip.downcase.split(/ [\ s,] + /)---#这对我来说更好 – Alex 2012-06-25 13:16:02

1

通过将所有这些电子邮件地址保留在单个字段中,您将失去很多Rails的强大功能。有很多方法可以帮助您设置操作,查找,验证,关联等,以避免您错过或不得不实施自己。这个问题只是一个例子。这样做的方式是为这些电子邮件创建一个单独的模型,将它们存储在每个电子邮件一个记录中,并将该模型与您的帐户模型相关联。

+0

我不反对......除了这个UI,我需要收集输入到一个单一的领域,在过去,我什么都没有,但是要管理一个可变数量的麻烦的相关领域。 – jpwynn 2011-06-11 18:07:28

3

在您的形式,如果你使用这样的格式,你可以提交值的集合:

&optional_email[][email protected]&optional_email[][email protected] 

你将代表这在您的形式,如:

Email 1: <%= text_field_tag 'optional_email[]' %> 
Email 2: <%= text_field_tag 'optional_email[]' %> 

这些也与工作模型帮手等

然后,轨道将弄清楚如何将这些参数变成一个集合,如:

params[:optional_email] = ['[email protected]', '[email protected]'] 

如果你不能做到这一点,一个办法是这个自己的控制器内部分裂:

@model.optional_emails = params[:optional_email].split(/[\,]/).map(&:strip) 

然后在这两种情况下,你可以写在每一个人的电子邮件工程验证,而无需使用巨大正则表达式。

根据数据的使用方式,可能会更适合使用电子邮件模型。如果您有理由不这样做,那么您可以在模型上使用serialize方法,以确保此字段始终是电子邮件的集合。

+0

嗨,谢谢,尽管我不太理解你的答案......我们需要用户能够将分隔的电子邮件字符串输入到文本字段中......要求用户也键入&optional_email并不是很实际。或者换一种方式,我们可以问,但是我们仍然必须处理他们做错了的情况... – jpwynn 2011-06-12 02:48:20

+0

对不起,这是表单提交参数的格式。用一个例子说明你如何从表单助手那里做到这一点。 – jdeseno 2011-06-12 03:29:58

+0

啊,我现在看到你的意思了,谢谢。这可能是“正确”的做法......但在我们的情况下,出于几个原因,我们确实必须让他们进入一个单一的领域...大,因为可以有多达10个和10个领域在屏幕上占用太多空间,而单个字段可以横向滚动以接受相当长的字符串。 – jpwynn 2011-06-12 03:43:16

2
validates :daily_recipients, 
    :format => { :with => /(\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})(,\s*([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,}))*\z)/i }, 
    :allow_blank => true