【问题标题】:How do I validate a virtual attribute in an ActiveRecord model?如何验证 ActiveRecord 模型中的虚拟属性?
【发布时间】:2009-07-13 15:50:43
【问题描述】:

我正在使用虚拟属性将标签从我的表单中以逗号分隔的文本框保存在 Entry 模型中(基于 Railscasts #167):

class Entry < ActiveRecord::Base
  has_many :entry_tags
  has_many :tags, :through => :entry_tags

  after_save :update_tags
  attr_writer :tag_names

  def tag_names
    tags.map(&:name).join(", ")
  end

  def update_tags
    if @tag_names
      self.tags = @tag_names.split(",").map do |name|
        Tag.find_or_create_by_name(name.strip)
      end
    end
  end
  private :update_tags
end

我想在我的标签名称上添加验证,但我不确定最好的方法是什么。我在 Tag 模型中定义了一个现有的验证方法:

class Tag < ActiveRecord::Base
  has_many :entry_tags
  has_many :entries, :through => :entry_tags

  validates_uniqueness_of :name
  validates_format_of :name, :with => /\A[a-z0-9_ -]*\Z/, :on => :create
end

但是,因为 update_tags 方法是在保存之后调用的,所以任何来自创建的验证错误都将在条目已经保存之后。

我正在考虑在入口模型中创建一个验证方法并在入口保存时调用它,但是:

  1. 如果我这样做,我不确定进行验证的最佳方法是什么。我是在Entry 中创建自己的验证,还是为每个名称创建一个Tag 对象并检查t.valid??我会以某种方式从Tag 收集验证错误消息或生成它们吗?
  2. 我不确定这是否是进行此类验证的正确方法。

有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails validation activerecord virtual-attribute


    【解决方案1】:

    如果你还没有排除,我会看看使用validates_associated

    【讨论】:

    • 我尝试将我的 update_tags 方法移动到称为 before_validation,这很有效,但似乎在保存时关联正在自动验证(我最终得到重复的错误消息一个无效的标签)。
    • validates_associated :tags真的够了吗?我有相同的代码,但我得到Failed to replace categories because one or more of the new records could not be saved. 而不是验证通知...
    • @chodorowicz 你有想过那个吗?我遇到了同样的错误。
    【解决方案2】:

    当您尝试将无效项目添加到关联时会出现此错误。一个可能的原因是您在输入数据后向关联模型添加了验证,而您当前在数据库中存在无效值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      相关资源
      最近更新 更多