Rails 模型验证,它检查是否已经存在具有某些属性的对象

Boz*_*vic 6 validation model ruby-on-rails

我有以下型号:

class TestModel < ActiveRecord::Base
  enum some_column: [:prop1, :prop2, :prop3]
end
Run Code Online (Sandbox Code Playgroud)

我想确保我在数据库中总是最多有一个带有 prop1 列值的对象,而我可以有多个带有 prop2 或 prop3 对象的对象,或者没有。如果它可以是模型验证,那就太好了。我尝试过这种方式,但不确定这是否是 Rails 应用程序的好习惯:

      if ((id.nil? and TestModel.where(some_column: 'prop1')) or (TestModel.where(some_column: 'prop1').where.not(id: id)))
Run Code Online (Sandbox Code Playgroud)

我尝试用左侧覆盖创建操作,用右侧覆盖更新。有什么方法可以做到这一点吗?

谢谢

更新

这是我的问题的解决方案

def only_one_prop1_record
  if(some_column == 'prop1')
    if new_record? #if create action
      if TestModel.where(some_column: 'prop1').any?
        errors.add(:base, 'You can only have one prop1 record')
      end
    elsif persisted? #if update action
      if TestModel.where(some_column: 'prop1').where.not(id: id).any?
        errors.add(:base, 'You can only have one prop1 record')
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

并像这样调用验证: validate :only_one_prop1_record

Dee*_*eep 5

这可能会帮助您:

class TestModel < ActiveRecord::Base
  enum some_column: [:prop1, :prop2, :prop3]

  validate :only_one_prop1_record, on: :create

  def only_one_prop1_record
    if TestModel.exists?(some_column: prop1)
      errors.add(:base, 'You can only have one prop1 record')
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

或者可以在其上运行的验证update,并create都可以试试这个:

def only_one_prop1_record
  existing_record = TestModel.where(some_column: prop1).first
  if (new_record? && existing_record.present?) || (persisted? && existing_record != self)
    errors.add(:base, 'You can only have one prop1 record')
  end
end
Run Code Online (Sandbox Code Playgroud)

on: :create从上面删除。