Ruby on Rails:before_save 字段为小写
Posted
技术标签:
【中文标题】Ruby on Rails:before_save 字段为小写【英文标题】:Ruby on Rails: before_save fields to lowercase 【发布时间】:2014-07-14 09:52:54 【问题描述】:我正在尝试将表单中的字段更改为小写,然后再将它们保存到数据库中。这是我的代码,但是数据库的输出仍然是大写的,为什么代码不起作用?
class Transaction < ActiveRecord::Base
validates :name, presence: true
validates :amount, presence: true, numericality: true
before_save :downcase_fields
def downcase_fields
self.name.downcase
end
end
【问题讨论】:
before_save |transaction| transaction.name.downcase! 这是一个老问题,但我认为值得指出的是这个想法会产生意想不到的后果。如果您等待像name
这样的小写,您实际上无法获得您认为得到的唯一性约束。这使您的客户的事情变得复杂。您可能希望在唯一性验证器中将此与不区分大小写结合起来。
【参考方案1】:
downcase
返回字符串的副本,不修改字符串本身。请改用downcase!
:
def downcase_fields
self.name.downcase!
end
更多详情请见documentation。
【讨论】:
如果我只想小写表单的一个值(而不是全部),这将如何工作。抱歉,RoR 新手【参考方案2】:您没有通过运行self.name.downcase
将name
设置为小写,因为#downcase
不会修改字符串,它会返回它。你应该使用 bang downcase
方法
self.name.downcase!
但是,我喜欢在模型中使用另一种方式:
before_save name.downcase!
【讨论】:
更好的使用尝试像before_save name.try(:downcase!)
@AshishGaur 不需要Object#try
,因为 OP 有一个存在验证集。
我的错。我直接看到的是答案而不是问题。【参考方案3】:
String#downcase
不会改变字符串,它只是返回该字符串的修改副本。正如其他人所说,您可以使用downcase!
方法。
def downcase_fields
name.downcase!
end
但是,如果您想坚持使用downcase
方法,那么您可以执行以下操作:
def downcase_fields
self.name = name.downcase
end
这会将 name 实例变量重新分配给对 name 的原始值调用小写的结果。
【讨论】:
【参考方案4】:其他代码更少的简单示例:
class Transaction < ActiveRecord::Base
validates :name, presence: true
validates :amount, presence: true, numericality: true
before_save self.name.downcase!
end
希望这会有所帮助!
【讨论】:
这是最好的答案。 冗余self
你可以避免它before_save name.downcase!
【参考方案5】:
调用downcase方法后需要使用感叹号,如果还想将运算结果保存到变量中。 所以对你来说将是可用的:
self.name.downcase!
不要忘记 .downcase! 替换仅适用于 ASCII 区域。
【讨论】:
【参考方案6】:另一种解决方案是删除before_save
并猴子补丁initialize
方法
def initialize(args = )
args[:name].downcase! if args[:name]
super
end
然后你可以说类似
irb(main)> t = Transaction.new name: 'BIGTRANSACTION'
irb(main)> t.name
=> "bigtransaction
【讨论】:
以上是关于Ruby on Rails:before_save 字段为小写的主要内容,如果未能解决你的问题,请参考以下文章
带有 MD5 摘要的 Rails 模型 before_save
思考Ruby On Rails的底层代码(Ruby on Rails 開發秘籍 | Ruby on Rails 快速入門)