2012-03-28 116 views
4

我有一个用devise + omniauth进行用户认证的应用程序。生成唯一的用户名(omniauth + devise)

在我的模型中,我的应用程序中的用户名是唯一。我不希望重复的用户名在我的应用程序中。

Facebook中的某些用户在其个人资料中没有定义的用户名。

我想生成一个唯一的用户名,如果用户没有在Facebook中定义的用户名。

例如,对于生成的密码我有这样的:

:password => Devise.friendly_token[0,20] 

我能在我的应用程序唯一的用户名,如果Facebook的用户没有在Facebook的用户名?

谢谢

回答

2

你可以采取电子邮件的一部分@符号之前,并添加有像水木清华USER_ID,或只采取电子邮件本身。或者你可以以某种方式结合fb响应的名字和姓氏。

+0

谢谢你,你能不能写个例子吗?谢谢@alony;)。我曾经想过:'user.username =“user _#{user.id.to_s}”'。我正在使用mongoid。我的ids是''4f72ee7e1d41c87cb1000001“'。我不知道我的修正是否正确! – hyperrjas 2012-03-28 11:05:50

+2

我总是这样做: 'user.username = user.email [/^[^ @] * /]',它看起来不错,但可能会重复。在你的情况下,你可以这样做:'user.username =“#{user.email [/^[^ @] * /]}##{user.id.to_s [0..5]}”' - 第一个6只是不要让它太长:) – alony 2012-03-28 11:35:23

+0

谢谢你对我的工作很好:D。但用0..5可能会重复吗?谢谢。 – hyperrjas 2012-03-28 13:00:18

10

您可以创建一个很好的可读用户名(例如从电子邮件的第一部分生成),然后通过添加数字直到它是唯一的。如这里

#in User 
def get_unique_login 
    login_part = self.email.split("@").first 
    new_login = login_part.dup 
    num = 2 
    while(User.find_by_login(new_login).count > 0) 
    new_login = "#{login_part}#{num}" 
    end 
    new_login 
end 

的一个问题是,有人可能的袋子,登录插图中你得到它,你保存它。所以,也许这是最好把它合并成一个before_create过滤:

#in User 
before_create :ensure_login_uniqueness 

def ensure_login_uniqueness 
    if self.login.blank? || User.find_by_login(self.login).count > 0 
    login_part = self.email.split("@").first 
    new_login = login_part.dup 
    num = 2 
    while(User.find_by_login(new_login).count > 0) 
     new_login = "#{login_part}#{num}" 
    end 
    self.login = new_login 
    end 
end 
+4

不应该在while循环结尾包含num + = 1? – Kombo 2013-04-22 18:17:54

+0

这真的很棒! – sp1rs 2013-06-03 14:47:39

+0

非常感谢!非常有帮助! – hyperrjas 2018-02-21 12:40:28

1

它没有为我工作,但变化:

while(User.find_by_login(new_login).count > 0) 

while(User.where(login: new_login).count > 0) 
2

这是我如何创建使用名字和姓氏字段组合登录..欢迎对此代码进行改进。

before_create :ensure_login_uniqueness 

    def ensure_login_uniqueness 
    if self.login.blank? 
     self.name = self.first_name + " " + self.last_name 
     firstnamePart = self.first_name.downcase.strip.gsub(' ', '').gsub(/[^\w-]/, '') 
     lastnamePart = self.last_name.downcase.strip.gsub(' ', '').gsub(/[^\w-]/, '') 
     login_part = firstnamePart+lastnamePart 
     new_login = login_part.dup 
     num = 1 
     while(User.where(:login => new_login).count > 0) 
     new_login = "#{login_part}#{num}" 
     num += 1 
     end 
     self.login = new_login 
    end 
    end 
+0

嘿戴夫,你能帮我解决这个问题吗?我试图将此添加到我的用户模型,但我得到的错误:Mysql2 ::错误:'where子句'中的未知列'users.login':SELECT COUNT(*)FROM'users' WHERE'用户'.'login '='bobweir' – thesowismine 2015-06-11 23:19:30

+0

我也尝试了一个更简化的版本,你可以在这里查看我的帖子,如果你想要的话:http://stackoverflow.com/questions/30793011/generating-meaningful-usernames-in-devise – thesowismine 2015-06-11 23:21:28

+0

@ thesowismine是否在用户表的迁移文件中添加了名为“login”的列。添加它将解决你的错误。 :) – Dave 2015-06-12 04:09:17

1

这里是我的方法,我使用为Facebook

def ensure_username_uniqueness 
    self.username ||= self.email.split("@").first 
    num = 2 
    until(User.find_by(username: self.username).nil?) 
     self.username = "#{username_part}#{num}" 
     num += 1 
    end 
    end 

    def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
     user.email = auth.info.email 
     user.password = Devise.friendly_token[0,20] 
     user.username = auth.info.name.downcase.gsub(" ", "") 
     user.username = user.username[0..29] if user.username.length > 30 
     user.ensure_username_uniqueness 
    end 
    end