如何在ActiveRecord模型中验证虚拟属性?

时间:2009-07-13 15:50:44

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

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

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方法,因此创建的任何验证错误都将在条目已保存之后。

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

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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

当您尝试向关联添加无效项时,会出现此错误。可能的原因是您在输入数据后向关联模型添加了验证,并且您当前在数据库中具有无效值。