Thi*_*ilo 46 mysql activerecord ruby-on-rails ruby-on-rails-3.1
是否有一种简单的方法(即配置)强制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
Run Code Online (Sandbox Code Playgroud)
哪个有效,但效率不高或干燥.我可以将其分解为一个方法并将其混合到ActiveRecord中,但在我走这条路之前,我想知道是否有办法做到这一点.
Sim*_*tti 50
是的,目前唯一的选择是使用回调.
before_save :normalize_blank_values
def normalize_blank_values
attributes.each do |column, value|
self[column].present? || self[column] = nil
end
end
Run Code Online (Sandbox Code Playgroud)
您可以将代码转换为mixin,以便将其轻松地包含在多个模型中.
module NormalizeBlankValues
extend ActiveSupport::Concern
included do
before_save :normalize_blank_values
end
def normalize_blank_values
attributes.each do |column, value|
self[column].present? || self[column] = nil
end
end
end
class User
include NormalizeBlankValues
end
Run Code Online (Sandbox Code Playgroud)
或者您可以在ActiveRecord :: Base中定义它以在所有模型中使用它.
最后,您还可以将其包含在ActiveRecord :: Base中,但在需要时启用它.
module NormalizeBlankValues
extend ActiveSupport::Concern
def normalize_blank_values
attributes.each do |column, value|
self[column].present? || self[column] = nil
end
end
module ClassMethods
def normalize_blank_values
before_save :normalize_blank_values
end
end
end
ActiveRecord::Base.send(:include, NormalizeBlankValues)
class User
end
class Post
normalize_blank_values
# ...
end
Run Code Online (Sandbox Code Playgroud)
dex*_*ter 19
尝试这个宝石是否有效:
https://github.com/rubiety/nilify_blanks
提供了一个框架,用于在数据库中将传入的空值保存为nil,而不是简单地使用空字符串...
在Rails中,当从表单保存模型并且用户不提供值时,会将空字符串记录到数据库而不是许多人希望的NULL(混合空白和NULL会变得混乱).此插件允许您指定属性列表(或所有属性中的异常),如果在保存模型之前它们为空,则将转换为nil.
只有属性响应空白?值为true的值将转换为nil.因此,这不适用于值为0的整数字段,例如......
另一个选择是提供自定义setter,而不是在钩子中处理它.例如:
def foo=(val)
super(val == "" ? nil : val)
end
Run Code Online (Sandbox Code Playgroud)
我的建议:
# 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21391 次 |
| 最近记录: |