是否有一种简单的方法(即配置)强制ActiveRecord在DB中将空字符串保存为NULL(如果列允许)?
原因是如果DB中的NULLable字符串列没有默认值,则不设置此值的新记录将包含NULL,而将此值设置为空字符串的新记录将不会NULL,导致数据库中的不一致,我想避免。
现在我在我的模特中做这样的事情:
before_save :set_nil
def set_nil
[:foo, :bar].each do |att|
self[att] = nil if self[att].blank?
end
end
哪个有效,但效率不高或干燥。我可以把它分解成一个方法并将它混合到ActiveRecord中,但在我走这条路之前,我想知道是否有办法做到这一点。
答案 0 :(得分:19)
尝试这个宝石是否有效:
https://github.com/rubiety/nilify_blanks
提供一个框架,用于在数据库中将传入的空白值保存为nil,在这种情况下,您宁愿使用DB NULL,而不仅仅是空字符串......
在Rails中,当从表单保存模型并且用户不提供值时,会将空字符串记录到数据库而不是许多人希望的NULL(混合空格和NULL会变得混乱)。此插件允许您指定属性列表(或所有属性中的异常),如果在保存模型之前它们为空,则将转换为nil。
只有属性响应空白?值为true的值将转换为nil。因此,这不适用于值为0的整数字段,例如......
答案 1 :(得分:7)
另一个选择是提供自定义setter,而不是在钩子中处理它。 E.g:
viewDidLoad()
答案 2 :(得分:4)
我的建议:
# app/models/contact_message.rb
class ContactMessage < ActiveRecord::Base
include CommonValidations
include Shared::Normalizer
end
# app/models/concerns/shared/normalizer.rb
module Shared::Normalizer
extend ActiveSupport::Concern
included do
before_save :nilify_blanks
end
def nilify_blanks
attributes.each do |column, value|
# ugly but work
# self[column] = nil if !self[column].present? && self[column] != false
# best way
#
self[column] = nil if self[column].kind_of? String and self[column].empty?
end
end
end
答案 3 :(得分:2)
对于necroposting很抱歉,但如果您需要指定字段的解决方案,我在答案中找不到确切的内容:
module EnforceNil
extend ActiveSupport::Concern
module ClassMethods
def enforce_nil(*args)
self.class_eval do
define_method(:enforce_nil) do
args.each do |argument|
field=self.send(argument)
self.send("#{argument}=", nil) if field.blank?
end
end
before_save :enforce_nil
end
end
end
end
ActiveRecord::Base.send(:include, EnforceNil)
这样:
class User
enforce_nil :phone #,:is_hobbit, etc
end
当我们说你有field1和field2时,执行某个字段很方便。 Field1在SQL中有唯一的索引,但可以是空白的,所以你需要强制执行(NULL被认为是唯一的,“” - 不是通过SQL),但对于field2你实际上并不关心,你已经有很多回调或方法,它们都有效当field2为“”时,如果field2为nil
,则会在错误层下挖掘您的应用。我面临的情况。
可能对某人有用。
答案 4 :(得分:0)
我使用attribute normalizer gem在属性进入db之前对其进行规范化。
答案 5 :(得分:0)
有一个方便的宝石可以在保存记录时自动执行此操作,无论是在用户表单中还是在控制台中或在rake任务中等。
它被称为 strip_attributes ,非常易于使用,开箱即用的默认设置。
默认情况下它会做两件事,几乎总是要完成:
剥去前导和尾随空格:
" My Value " #=> "My Value"
将空字符串转换为NULL
:
"" #=> NULL
" " #=> NULL
您可以使用以下命令将其添加到您的gem文件中:
gem strip_attributes
将其添加到要删除前导/尾随空格的任何(或所有)模型,并将空字符串转换为NULL
:
class DrunkPokerPlayer < ActiveRecord::Base
strip_attributes
end
您可以基于每个模型传递其他选项来处理异常,例如,如果您想要保留前导/尾随空格等等。
您可以在此处查看GitHub存储库中的所有选项: