2011-02-02 10 views
45

rails3のテーブルに最新のレコードを見つける方法があるのだろうか?Rails 3で最新のレコードを探す

おかげ

エリオット

+0

あなたが話しているテーブルについてもっと知る必要があります。レコードが追加または変更されたときに自動的に更新される日時フィールドはありますか? –

答えて

98

Postモデルを考えると、あなたは私だけではなかった@post = Post.order("created_at").last

(理由を行うことができます@post = Post.lastは、常にデフォルトのプライマリキー(通常はid)でソートされるためです。これはうまくいきますが、問題が発生する可能性があるシナリオがあることは間違いありません。レコードにカスタムIDを設定する、プライマリキーの順序付け/自動番号付けに影響を与えるデータベースの変更など)。 created_atタイムスタンプでソートすると、実際に最新のレコードが取得されます。

+9

このメソッドを使用する場合は、必ずcreated_atフィールドのインデックスを作成してください。 – jemminger

+1

'before_validation'フックでは動作しません。 – Green

+1

Rails 4では、 'Default_scope {order(created_at::asc)}'行をPostモデルに追加して 'Post.last'が期待どおりに動作するようにすることもできます。 – sambecker

1

てみてください、ModelNameという名前のモデルのために:

record = ModelName.last 
+2

これは、テーブルのソート順を考慮していません。 postgresデータベースを使用すると失敗するでしょう – jamesc

+1

それは失敗するでしょう...素晴らしい。あなたは失敗を避けるために何をしますか? –

3

モデルがポストと呼ばれている場合は、[はい、あなたはそのように

.lastメソッドを使用することができます。

>> Post.last 
=> #<Post ...> 
18

dmarkowの答えは、技術的に正しいですが、あなたはcreated_atとのインデックスを作成する必要がありますデータベースの拡大に伴ってクエリがますます遅くなる危険性があります。

「id」列が自動インクリメントの主キー(可能性が高い)であることがわかっている場合は、それが定義でインデックスであるため、単に使用してください。

また、ARELがfind(:last)内のレコードを1つだけ選択するように最適化されていない限り、すべてのレコードを選択するリスクがあります。最後に "last()"メソッド。より効率的なものに結果を制限することです:

MyModel.last(:order => "id asc", :limit => 1) 

または

MyModel.first(:order => "id desc", :limit => 1) 
+6

'@post = Post.order(" created_at ")。last'は実際に正しいことをします。コンソール出力は 'SELECT" posts "。* FROM" posts "ORDER BY" posts "と同じです。" created_at "DESC LIMIT 1' – PhilT

2

あなたは十分に高トラフィックのテーブルの上にcreated_atを使用してあいまいさの問題に遭遇することがあります。

例えば、試してみてください。

INSERT INTO table (created_at) VALUES (NOW()); 
INSERT INTO table (created_at) VALUES (NOW()); 

は、解像度のみの1秒を持っている同じcreated_atを持っている可能性を秘めて、..has。ソートは特定の順序でそれらを返すでしょう。

マイクロ秒値を保存して並べ替える方がよい場合があります。

関連する問題