如何从所有用户的电子邮件中设置用户名?

时间:2012-07-09 12:33:30

标签: ruby-on-rails ruby ruby-on-rails-3 rake rake-task

我想创建rake任务来设置所有用户的用户名'在' @'之前没有用户名的部分在他们的电子邮件地址因此,如果我的电子邮件是test@email.eu,我的用户名应该成为测试版。如果它不可用,请用数字(1)作为前缀。

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

我当然在User模型中对用户名进行了uniqness验证。

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

3 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:1)

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

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

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

你可以使用的另一件事是rubys重试机制。只是让active-record引发错误并使用更改的用户名重试。

begin
   do_something # exception raised
rescue
   # handles error
   retry  # restart from beginning
end

答案 2 :(得分:0)

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