1

メールアドレスの「@」の前の部分にユーザー名を付けずに、すべてのユーザーのユーザー名を設定する rake タスクを作成したいと考えています。したがって、私のメールアドレスが test@email.eu の場合、ユーザー名は test になります。利用できない場合は、先頭に数字 (1) を追加します。

そのため、ユーザー名の一意性をチェックする魔女に問題があります。以下のコードは、2 番目のループの後に機能しません。例: 3 つの電子メールがある場合: 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ブランチの既存のユーザーのユーザー名を変更していますか?それは良い考えではないように見えます。

また、実際のファインダーを使用して、ユーザー名を持たないユーザーを選択する必要があります。それ以外の場合は、選択する前にすべてのユーザーをロードします。

「要件に一致する」かどうかはわかりませんが、重複の問題が発生しないように、ユーザー名に乱数を付けることができます。

使用できるもう1つのものは、rubysの再試行メカニズムです。active-recordにエラーを発生させ、変更したユーザー名で再試行してください。

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

queryUser.find_by_username(username)では、1 つのレコードのみが提供されることを期待しています。したがって、必要はありませんeach。別の方法でインデックスを追加する必要があります。

于 2012-07-09T13:13:48.650 に答える