我是Rails验证的新手,虽然我已经看到了一些相关的问题,但我无法想出如何将它们扩展到我的情况。
我需要允许用户设置其帐户,以输入最多N(系统范围的常量,如10个)可选电子邮件地址。
因此用户输入文本字段的数据可能类似于
foo@bar.com
或
foo@bar.com, foo2@bar2.com,foo3@bar3.com , foobar4@domain.com
(注意逗号之前或之后空格的使用不一致,典型的真实用户内容)
目前在我的模型中我处理单个可选电子邮件并使用正则表达式:
validates :alert_email,
:allow_blank => true,
:length => {:minimum => 3, :maximum => 254},
:format => {:with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i}
可能有某种超级正则表达式,我可以用......取代......如果有人能提供帮助,那就没关系了。但是为了便于阅读(并且因为性能是无关紧要的,因为这是每个用户执行一次)我认为我应该以某种方式将验证移动到暴力解析它们并一次运行一个正则表达式的方法?
PS我还希望我的验证例程能够“修复”空格/逗号的内容,因此列表中的项目之间总是有逗号空间,并且具有已保存的固定版本。我猜我做了一些before_xxxxx方法?
答案 0 :(得分:4)
您可以使用Ruby split
方法将电子邮件列表分成数组,使用连接方法将它们保存为通用格式。
before_validation do
emails = self.emails.split(/\s+,\s+/)
emails.each do |email|
self.errors.add(:emails, "invalid email") unless email =~ /([^\s]+)@([^\s]+)/
end
self.emails = emails.join(",")
end
答案 1 :(得分:3)
如果您使用以下格式,则可以在表单中提交值集合:
&optional_email[]=email1@example.com&optional_email[]=email2@example.com
您可以在表单中表示:
Email 1: <%= text_field_tag 'optional_email[]' %>
Email 2: <%= text_field_tag 'optional_email[]' %>
这些也适用于模型助手等。
然后rails将弄清楚如何将这些参数转换为如下集合:
params[:optional_email] = ['email1@example.com', 'email2@example.com']
如果你不能这样做,另一种选择就是将你自己分成控制器:
@model.optional_emails = params[:optional_email].split(/[\,]/).map(&:strip)
然后在任何一种情况下,您都可以编写一个适用于每个电子邮件的验证,而无需使用巨大的正则表达式。
根据您的数据使用方式,您可以更好地使用电子邮件模型。如果您有理由不这样做,可以在模型上使用serialize
方法,以确保此字段始终是电子邮件的集合。
答案 2 :(得分:2)
validates :daily_recipients,
:format => { :with => /(\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})(,\s*([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,}))*\z)/i },
:allow_blank => true
答案 3 :(得分:1)
通过将所有这些电子邮件地址保留在一个字段中,您将失去Rails的许多功能。有大量的方法可以帮助您设置操作,查找,验证,关联等,您将错过或必须自己实施。这个问题只是一个例子。 rails的方法是为这些电子邮件创建一个单独的模型,每封电子邮件存储一条记录,并将该模型与您的帐户模型相关联。