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
哪个有效,但效率不高或干燥.我可以将其分解为一个方法并将其混合到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
您可以将代码转换为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
或者您可以在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
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
我的建议:
# 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
| 归档时间: | 
 | 
| 查看次数: | 21391 次 | 
| 最近记录: |