10

私は、(とりわけ)本番データベースをローカルマシンに複製し、すべてのユーザーパスワードをpassword(またはその他のものに)リセットするrakeタスクを持っています。

私の現在の実装は次のようになります。

User.find_each do |user|
  user.password = 'password'
  user.save
end

そして、それはうまくいきます。しかし、ユーザーが 1000 人を超えた現在、速度はかなり低下しており、さらに悪化することは確実です。

編集

わかった。ここに部分的な答えがあります:

Devise.stretches = 1
User.find_each do |user|
  user.password = 'password'
  user.save
end
Devise.stretches = 10

これにより、約5〜10倍の速度向上が得られました。SQL ベースのソリューションと比較するとまだ遅いかもしれませんが、それでも非常に優れた改善です。これは、少なくとも 10,000 ユーザーにスケーリングする必要があります。

時間があれば、SQL ソリューションをいじるかもしれません。

私はこの質問を少し開いたままにします。他の誰かがより良い解決策を持っている場合は、投稿してください。

最終的な回答/最良の解決策

いくつかのコメントが示唆しているように、最速の解決策は SQL 経由で一括更新を実行することです。Devise では、以下をencrypted_password直接設定できるようになりました。

sample_user = User.last
sample_user.password = "password"
encrypted_password = sample_user.encrypted_password
User.update_all(encrypted_password: encrypted_password)

基本的に、単一のユーザーにパスワードを設定すると、そのユーザーを使用しencrypted_passwordて一括更新を実行できます。このソリューションは、実質的に任意の数のユーザーに拡張する必要があります。

以下のコメントでこのソリューションを提案してくれた @vladCovaliov のおかげです。

4

1 に答える 1

2

通常、私はあなたが望むSQLを書くと言うでしょう、例えば

ActiveRecord::Base.connection.execute(' update users set encrypted_password = 'password') 

ただし、通常、パスワードは暗号化されており、MD5 または Devise や Authlogic などの承認/認証メカニズムを使用して直接暗号化します。その場合、一致する必要があるパスワードとパスワード確認値 (Rails でレコードを作成するとき) を渡して、実際にパスワードを作成または変更します。一致する場合、パスワードは暗号化され、実際にデータベースに保存されます。これらの理由から、ダイレクト SQL でハッシュ アルゴリズムを使用しない限り、これは 1 つずつ行う必要があります。

それは次のように単純かもしれません

ActiveRecord::Base.connection.execute(' update users set password = md5('password'))
于 2012-09-11T00:07:23.453 に答える