我想创建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
答案 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
。您应该以另一种方式添加索引。