我们有一个带谷歌登录/注册的Facebook应用程序。某些帐户不提供用户名,因此应用程序必须先创建一个用户名,然后才能将对象保存在数据库中。
我们目前以这种方式解决问题:
user.username = "#{user.email[/^[^@]*/]}_#{user.id.to_s}"
问题是,我们使用mongodb/mongoid
之类的database/odm
并生成一个太长的用户名,例如:
hyperrjas_50ad43d11d41c86b27000066
在这种情况下,我们在user.id
之后添加了hyperrjas
。
如果已经使用了用户名,我们希望添加唯一的号码而不是唯一的id
,例如:
hyperrjas
hyperrjas1
hyperrjas2
hyperrjas3
...
我们怎么做?
答案 0 :(得分:2)
我回答了类似于此前的问题。这就是我想出的:
https://stackoverflow.com/a/13794784/367611
每条评论更新
您可以通过以下方式制定方法:
def prevent_collision(user)
name = "#{user.email[/^[^@]*/]}"
users = User.where(:username => /^#{name}/).to_a #Return an array and after use length method with users.length. Without .to_a is not working because is returned a mongoid criteria.
count = users.length
if count > 0
count = rand(1000)
loop do
break "#{name}#{count}" unless users.any? { |u| u.name == "#{name}#{count}" }
count += rand(10)
end
else
name
end
end
返回值将是最初生成的名称或附加了计数的名称。然后你可以做,例如:
@user.username = prevent_collision(@user)
@user.save
答案 1 :(得分:1)
也许这是一个有用的想法:
username = "hyperrjas001"
try_name = username.dup
10.times do
raise "username maximum reached: #{username}." if try_name.end_with('999')
try_name = try_name.next
puts try_name
end
# Output:
#hyperrjas002
#hyperrjas003
#hyperrjas004
#hyperrjas005
#hyperrjas006
#hyperrjas007
#hyperrjas008
#hyperrjas009
#hyperrjas010
#hyperrjas011
答案 2 :(得分:0)
这样的东西可能适合增量:
username.sub(/^(.*\D)(\d*)$/) { "%s%d" % [ $1, $2.to_i + 1 ] }
举个例子:
username = 'hyperrjas'
username2 = username.sub(/^(.*\D)(\d*)$/) { "%s%d" % [ $1, $2.to_i + 1 ] }
# => "hyperrjas1"
username3 = username2.sub(/^(.*\D)(\d*)$/) { "%s%d" % [ $1, $2.to_i + 1 ] }
# => "hyperrjas2"
可以根据需要重复此操作,直到获得唯一名称。请注意,它会将lucky99
等名称变为lucky100
,而不是lucky991
。