Rails custom validation - Only one record can be t

2020-05-25 11:08发布

问题:

I'm trying to write a validation where only one record can be true. I have a 'game' model with an 'active' boolean column, only one game can be active at any time, so if someone tries to create a new 'game' record when there is an already active game then they should get an error. Below is what I currently have but isn't working!

validate :active_game

  def active_game
    if active == true && Game.find_by(active: true) == true
       errors[:name] = "a game is already active!"
    end
  end

回答1:

You also need to check against the ID if the record is already persisted. Otherwise, saving the active game again would not succeed because there is an existing active game, which happens to be itself.

validate :only_one_active_game
scope :active, where(:active => true)

protected

def only_one_active_game
  return unless active?

  matches = Game.active
  if persisted?
    matches = matches.where('id != ?', id)
  end
  if matches.exists?
    errors.add(:active, 'cannot have another active game')
  end
end


回答2:

I think you can just check the uniqueness of active_game when it is true.

validates_uniqueness_of :active_game, if: :active_game



回答3:

Try using the exists? method. Also, add the error using the add method.

validate :active_game
scope :active, where(active: true)

  def active_game
    if active && Game.active.where("id != ?", id).exists?
       errors.add(:name, "a game is already active!")
    end
  end