9

在 Rails 模型中,如果我有一个用于专有名称的字段,那么确保它们统一大写的最佳实践方法是什么,尽管用户可能会懒惰输入?

IE 假设模型是Contact,字段是Name. 无论用户输入什么,我都希望将单词大写,即模型会将以下输入转换为以下输出:

john doe -> John Doe
j doe -> J Doe
John doe -> John Doe
john doe jr -> John Doe Jr

那么,您是创建一个before_save回调并使用正则表达式转换该字段,还是创建某种验证或其他不同的东西?我非常感谢强调基本原理的答案,为什么你会以这种或另一种方式做,因为这是我最坚持的。

4

4 回答 4

18

你想要的方法是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
于 2012-04-18T13:49:37.617 回答
8

@tserif 的更简洁的演绎如下:

def name=(s)
    super s.titleize
end

这消除了对指定属性名称的依赖write_attribute和需要,name以支持更原始的方法。to_s除非您想要分配符号的能力,否则我认为不需要。

于 2013-02-01T22:13:23.930 回答
4

我建议使用 before_save 。

就像你的模型一样:

before_save :capitalize_name

def capitalize_name
  self.name = self.name.split.collect(&:capitalize).join(' ') if self.name && !self.name.blank?
end
于 2012-04-18T13:40:37.823 回答
3

最重要的问题是您将如何显示名称?如果它像我猜的那样在网络上,我根本不会在模型中处理这个问题。最简单的解决方案是只使用 csstext-tansform: capitalize;来处理大写,但如果您经常显示它,您可能需要定义一个装饰器或辅助方法来为您规范化它。

def full_name
  [first_name, last_name].map { |name| name[0].upcase + name[1..-1] }.join(' ')
end

请注意,capitalize您只想将第一个字母大写,而不是映射。名为 RJ 或 CJ 的人可能希望 J 保持大写。

无论如何,数据都是规范的,看到大写的部分纯粹是显示。

于 2012-04-18T13:41:14.840 回答