有很多通过关联的范围验证

时间:2015-05-22 05:21:37

标签: ruby-on-rails ruby validation

我有一个has_many通过:使用Token作为连接模型的UserUserToken之间的关联。我想在作用于特定用户的Token模型的validate_uniqueness_of属性上有device_name

意思是,如果已经为具有相同device_name的用户创建了令牌记录,我只想验证device_name唯一性。通常一个人可以这样做:validates_uniqueness_of :device_name, scope: :user_id但是user_id不是Token的属性,这个属性在连接表中......我很难弄清楚如何在Rails中创建这个验证。我知道你可以在数据库级别用索引做,但是如果可能的话我想通过验证来做。有什么想法吗?

class Token < ActiveRecord::Base
   has_many :user_tokens
   has_many :users, through: :user_tokens

   validates_uniqueness_of :device_name, scope: #only validate if there is already a Token for this user with this device_name.
end

class User < ActiveRecord::Base
   has_many :user_tokens
   has_many :tokens, through: :user_tokens
end

class UserToken < ActiveRecord::Base
   belongs_to :user
   belongs_to :token
end

2 个答案:

答案 0 :(得分:1)

由于您无法使用user_id模型中的内置验证帮助程序访问Token属性,因此使用自定义验证程序可能会为您提供更多灵活性实现您正在寻找的验证:

http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#performing-custom-validations

希望这有帮助!

答案 1 :(得分:1)

通过创建以下自定义验证,我能够实现我想要的目标。

validate :unique_device_name_per_user?

def unique_device_name_per_user?
  user = User.find(user_tokens.first.user_id)
  token = user.tokens.where(device_name: device_name)

  if token.present?
    self.errors.add(:device_name, ": This user has already registered this device_name.")
  end
end