在Rails模型中,如果我有一个专有名称的字段,尽管用户可能有懒惰的输入,但确保它们统一大写的最佳实践方法是什么?
IE假设模型为Contact
,字段为Name
。无论用户输入什么,我希望单词大写,即模型会将以下输入转换为以下输出:
john doe -> John Doe
j doe -> J Doe
John doe -> John Doe
john doe jr -> John Doe Jr
那么,你是创建一个before_save
回调并用正则表达式转换字段,还是创建某种验证或不同的东西?我非常感谢答案,重点是理由,为什么你会这样或那样做,因为这是我最坚持的。
答案 0 :(得分:14)
您想要的方法是titleize
。 capitalize
方法仅执行整个字符串中的第一个字符"john doe".capitalize #=> "John doe"
,"john doe".titleize #=> "John Doe"
。
至于如何实现它,你可以使用before_save
,但我喜欢使用伪属性进行这些类型的单个属性的简单准备。基本上,您为属性定义writer
方法,该方法将隐藏由ActiveRecord
创建的默认属性。您仍然可以使用write_attribute
方法(docs)访问该属性。这样做可以确保在分配属性时正确设置属性,这意味着即使在保存之前,您也可以确保对象处于有效状态:
class Contact < ActiveRecord::Base
def name=(s)
write_attribute(:name, s.to_s.titleize) # The to_s is in case you get nil/non-string
end
end
答案 1 :(得分:8)
@ tserif的清洁演绎如下:
def name=(s)
super s.titleize
end
这消除了对write_attribute
的依赖性以及需要指定属性名name
以支持更原始的方法。除非您希望能够分配符号,否则我认为不需要to_s
。
答案 2 :(得分:3)
我建议使用before_save。
像你的模特一样:before_save :capitalize_name
def capitalize_name
self.name = self.name.split.collect(&:capitalize).join(' ') if self.name && !self.name.blank?
end
答案 3 :(得分:3)
最重要的问题是你将如何展示名字?如果它会在网上,正如我猜的那样,我根本不会在模型中处理这个问题。最简单的解决方案是使用css text-tansform: capitalize;
来处理大小写,但是如果你经常显示它,你会想要定义一个装饰器或辅助方法来为你规范它。
def full_name
[first_name, last_name].map { |name| name[0].upcase + name[1..-1] }.join(' ')
end
请注意,您只需要将第一个字母大写,而不是映射capitalize
。名为RJ或CJ的人可能希望J保持大写。
数据是规范的,看到大写的部分是纯粹的显示。