2012-07-09 68 views
1

我想創建rake任務,將沒有用戶名的所有用戶的用戶名設置爲他們電子郵件地址中「@」之前的部分。所以如果我的電子郵件是[email protected],我的用戶名應該成爲測試。如果它不可用,請用數字(1)作爲前綴。如何從所有用戶的電子郵件設置用戶名?

所以我有問題女巫檢查用戶名的uniqness。下面的代碼在第二個循環後不工作:當我有三封電子郵件:[email protected][email protected][email protected] [email protected]的用戶名將爲空。

我當然有用戶模型中的用戶名的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 

其他的想法是要點:https://gist.github.com/3067635#comments

+1

是否有一個原因,你不能只使用完整的電子郵件地址作爲用戶名?當然,這保證了獨特性。 – 2012-07-09 13:05:24

+0

是這是在我的應用程序的規範,它將在其他模型中用作索引鍵 – tomekfranek 2012-07-09 13:10:24

回答

3

你可以使用一個簡單的循環,同時檢查用戶名:

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 

但是,它可能是一個更好的方法來要求用戶在下次登錄時輸入用戶名。

+0

這僅適用於數據庫中沒有用戶名的舊用戶 – tomekfranek 2012-07-09 13:13:05

+0

@regedarek,你是什麼意思?你試過這個解決方案嗎?它完全符合你的要求。 – Mischa 2012-07-09 13:15:58

+0

我認爲這是對已被刪除的問題的回答。但當然這是我的解決方案。謝謝。我只將'''prefix'''改成'''prefix.to_s''' – tomekfranek 2012-07-09 13:19:13

1

如果我理解你的代碼是正確的,要更改現有用戶的用戶名在else分支?這看起來不是一個好主意。

您還應該使用真正的查找器來選擇沒有用戶名的用戶。否則你將在加載所有用戶之前加載它們。

我不知道它是否「符合您的要求」,但您可以隨便輸入一個用戶名,以免出現重複問題。

你可以使用的另一件事是ruby重試機制。只是讓主動記錄引發錯誤,然後用更改後的用戶名重試。

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

我不會更改用戶名,我只爲沒有用戶名的用戶執行此操作。 – tomekfranek 2012-07-09 13:14:17

0

在您的查詢User.find_by_username(username)中,您只希望提供1條記錄。所以你不需要任何each。您應該以另一種方式添加您的索引。

+0

是的,當然我把它改成了'''User.where {:username =>無}'' – tomekfranek 2012-07-09 13:15:47

相關問題