Rails关联的自定义验证

时间:2017-11-23 20:37:02

标签: ruby-on-rails

我有tre模型

class ChallengeItem < ApplicationRecord
  has_many :photos
end

class Photo < ApplicationRecord
  belongs_to :challenge_item
  has_many :votes
end

class Vote < ApplicationRecord
  belongs_to :photo
  validate :vote_per_foto

  private

  def vote_per_foto
    if self.class.exists?(photo_id: photo_id, voter_string: voter_string)
      errors.add :vote, 'already voted'
    end
  end
end

基本上每组照片(ChallengeItem)用户只能投一张照片。 每个投票都有一个名为voter_string

的指纹属性

我写了一个自定义验证,但通过此验证我只接受一张照片投票。我需要为每组照片投一票......

我该如何解决?

3 个答案:

答案 0 :(得分:1)

使用scope选项查看#uniqueness验证器以限制一个关联记录。你可以做点什么

validates :voter_string, uniqueness: { scope: { :photo_id } }

根据给定的Vote获得给定voter_string一个photo_id

答案 1 :(得分:0)

您需要检查challenge_item

中的任何照片是否存在投票
def vote_per_foto
  if self.class.exists?(photo_id: photo.challenge_item.photos.select(:id), voter_string: voter_string)
    errors.add :vote, 'already voted'
  end
end

答案 2 :(得分:0)

您要做的是设置间接关联:

class ChallengeItem < ApplicationRecord
  has_many :photos
  has_many :votes, through: :photos
end

class Photo < ApplicationRecord
  belongs_to :challenge_item
  has_many :votes
end

class Vote < ApplicationRecord
  belongs_to :photo
  has_one :challenge_item, through: :photo
  validate :one_vote_per_challenge_item

  def one_vote_per_challenge_item
    if challenge_item.votes.exists?(voter_string: voter_string)
      errors.add :base, 'already voted'
    end
  end
end

这样您就可以从照片实例访问challenge_item,而Rails会为您处理加入。