1

我想创建 rake 任务以将所有用户的用户名设置为他们电子邮件地址中“@”之前的部分,而没有用户名。因此,如果我的电子邮件是 test@email.eu,我的用户名应该变成 test。如果它不可用,请在其前面加上一个数字 (1)。

所以我有问题女巫检查用户名的唯一性。下面的代码在第二个循环后不起作用例如:当我有三封电子邮件时:test@smt.com、test@smt.pl、test@oo.com test@oo.com 的用户名将为空。

我当然对用户模型中的用户名进行了唯一性验证。

desc "Set username of all users wihout a username"
task set_username_of_all_users: :environment do
  users_without_username = User.where(:username => ["", nil])
  users_without_username.each do |user|
    username = user.email.split('@').first
    users = User.where(:username => username)
    if users.blank?
      user.username = username
      user.save
    else
      users.each_with_index do |u, index|
        pre = (index + 1).to_s
        u.username = username.insert(0, pre)
        u.save
      end
    end
  end
end

其他想法在 Gist 中:https ://gist.github.com/3067635#comments

4

3 回答 3

3

您可以使用一个简单的 while 循环来检查用户名:

users_without_username = User.where{ :username => nil }
users_without_username.each do |user|
  email_part = user.email.split('@').first
  user.username = email_part
  prefix = 1
  while user.invalid?
    # add and increment prefix until a valid name is found
    user.username = prefix.to_s + email_part
    prefix += 1
  end
  user.save
end

但是,要求用户在下次登录时输入用户名可能是更好的方法。

于 2012-07-09T13:12:14.397 回答
1

如果我理解您的代码正确,您正在更改 else 分支中现有用户的用户名?这看起来不是一个好主意。

您还应该使用真正的查找器来选择没有用户名的用户。否则,您将在选择所有用户之前加载所有用户。

我不知道它是否“符合您的要求”,但您可以在用户名中输入一个随机数,这样您就不会遇到重复的问题。

您可以使用的另一件事是 ruby​​ 的重试机制。只需让活动记录引发错误并使用更改的用户名重试即可。

begin
   do_something # exception raised
rescue
   # handles error
   retry  # restart from beginning
end
于 2012-07-09T13:10:40.157 回答
0

在您的查询User.find_by_username(username)中,您只希望提供 1 条记录。所以你不需要任何each. 您应该以另一种方式添加索引。

于 2012-07-09T13:13:48.650 回答