web-dev-qa-db-ja.com

Railsでモデルオブジェクトを「更新」するタイミングを知るにはどうすればよいですか?

私が持っている統合テストの一部は次のとおりです。

user = User.first
assert !user.is_active?

get confirm_email_user_url(user),:confirmId => user.mail_confirmation_hash

assert_equal response.status,200
# because confirm_email_user_url modifies the activation state of the object
user = User.first
assert_equal user.state,"activated"

これをデバッグするのに最後の1時間を費やしました:)。私の初期バージョンでは、confirm_email_user_urlにアクセスした後、userを再初期化しておらず、ユーザーがアクティブ化されていても、状態は常にinactiveでした。

モデルオブジェクトを "リロード"(より良い名前の欠如)すべきかどうかを知るにはどうすればよいですか?そうするために何を呼ぶべきですか?

60
Geo

データベースでデータが変更されるたびに user.reload を呼び出す必要があります。

上記のコードでは、User.firstによってデータベースからフェッチされたデータからメモリ内に「ユーザー」オブジェクトが作成されます。次に、confirm_email_user_urldatabaseを変更するように見えます。オブジェクトは、データベースからデータを再取得するreloadになるまで、これを認識しません。

オブジェクトをリロードする必要がある時期をプログラムで知る方法があるかどうかはわかりませんが、開発者として、何が起こっているのかを認識し、適切に処理する必要があります。私の経験のほとんど(多少制限されています)では、これはテスト中の問題にすぎません。本番環境では、メモリにロードされているオブジェクトをデータベースで変更することは一般的ではありません。通常、メモリ内のオブジェクトが変更され、データベースに保存されます(つまり、user.email = "[email protected]"に続いてuser.save)。多数のユーザーが連続して何かを変更する可能性のあるアクティビティの多いアプリケーションがある場合は、注意が必要です。

127
dantswain

ところでモデル自体にReport.count。列情報をリセットするか、最初/最後のレコードのインスタンスを取得してリロードしようと何度も試みた後、私が助けた唯一のことは、次のようなカウント間でデータベースを再接続することでした:

initial_count = Report.count

# do something, like invoking a rake task that imports the reports, ..

Report.connection.reconnect!
final_count = Report.count

これはRails 2.3.8+で動作しました。3+バージョンについては知りません。

6