Ruby on rails Facebook omniauth:确保用户名唯一

Ruby on rails Facebook omniauth:确保用户名唯一,ruby-on-rails,devise,omniauth-facebook,Ruby On Rails,Devise,Omniauth Facebook,我有一个应用程序,使用Desive+omniauth进行用户身份验证。 在我的用户模型中,我希望确保User.name是唯一的,以便我的应用程序中没有重复的用户名 环顾四周后,我得出了以下代码: User.rb validates :name, presence: true, uniqueness: true, length: {minimum: 6, maximum: 30} def ensure_username_uniqueness uniqname = (self.na

我有一个应用程序,使用Desive+omniauth进行用户身份验证。 在我的用户模型中,我希望确保User.name是唯一的,以便我的应用程序中没有重复的用户名

环顾四周后,我得出了以下代码:

User.rb

  validates :name, presence: true, uniqueness: true, length: {minimum: 6, maximum: 30}

  def ensure_username_uniqueness
    uniqname = (self.name).dup     
    num = 1
    until(User.find_by(name: uniqname).nil?) do ## returns true, should be false ##
      uniqname = self.name+"-#{num}"    
      num += 1
    end    
    self.name = uniqname      
  end  

  private  

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid        
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]
      user.name = auth.info.name[0..29].downcase.gsub(" ", "-")
      user.ensure_username_uniqueness           
      user.remote_avatar_url = auth.info.image
      user.skip_confirmation!
    end
  end   
当我使用数据库中已经存在的名称测试Facebook注册时,我会被重定向到注册页面(意味着注册失败)

我设置了binding.pry并注意到'until'循环没有执行,因为它返回true(即使名称已经存在)。我似乎不明白为什么循环没有被执行


任何帮助都将不胜感激

的结尾,直到

until(User.find_by(name: uniqname).nil?) do

结束时,您将被错过
do
,直到

until(User.find_by(name: uniqname).nil?) do

这里的问题似乎是,Desive中以前的操作已经“确定”了用户模型的范围,仅限于正在创建的新用户。因此,当您的sure\u username\u university()方法被调用时,
User.find\u by()
不会搜索整个数据库。相反,Desive增加了过滤结果的附加条款

使代码正常工作的一个快速修复方法是对用户
user.unscoped
user.default\u scoped
,这样您的查询将脱离当前范围并搜索所有用户:


这里的问题似乎是,Desive中以前的操作已经“确定”了用户模型的范围,仅限于正在创建的新用户。因此,当您的sure\u username\u university()方法被调用时,
User.find\u by()
不会搜索整个数据库。相反,Desive增加了过滤结果的附加条款

使代码正常工作的一个快速修复方法是对用户
user.unscoped
user.default\u scoped
,这样您的查询将脱离当前范围并搜索所有用户:


您应该了解,新用户将调用
first\u或\u create
的块,而不是first。是的,我理解。我创建了一个具有唯一名称的Desive用户,例如“mock name”,然后尝试使用具有相同名称的facebook和omniauth与其他用户登录。结果是我被重定向到注册页面。您应该了解,新用户将调用
first\u块或\u create
,而不是first块。是的,我了解。我创建了一个具有唯一名称的Desive用户,例如“mock name”,然后尝试使用具有相同名称的facebook和omniauth与其他用户登录。结果我被重定向到注册页面。