1

我们有一个带有谷歌登录/注册的 Facebook 应用程序。一些帐户不提供用户名,因此应用程序必须在将对象保存到数据库之前创建一个。

我们目前是这样解决问题的:

user.username = "#{user.email[/^[^@]*/]}_#{user.id.to_s}"

问题是,我们使用mongodb/mongoidlikedatabase/odm并生成了一个太长的用户名,比如:

hyperrjas_50ad43d11d41c86b27000066

在这种情况下,我们添加了user.idafter hyperrjas

id如果用户名已经被占用,我们想添加一个唯一编号而不是唯一编号,例如:

hyperrjas
hyperrjas1
hyperrjas2
hyperrjas3
...

我们该怎么做?

4

3 回答 3

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
于 2012-12-13T17:44:24.220 回答
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
于 2012-12-13T17:00:58.550 回答
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"

这可以根据需要重复,直到您获得唯一的名称。请注意,它会破坏名称,例如lucky99to lucky100,但不是lucky991

于 2012-12-13T16:39:48.603 回答