2011-02-02 23 views
45

Zastanawiam się, czy jest sposób na znalezienie najnowszej płyty w tabeli w rails3?Znajdź najnowszy rekord w Railsach 3

Dzięki

Elliot

+0

Musimy wiedzieć więcej na temat stołu, o którym mówisz. Czy istnieje pole datetime, które jest automatycznie aktualizowane po dodaniu i/lub zmianie rekordu? –

Odpowiedz

98

Given model Post, można zrobić @post = Post.order("created_at").last

(Powodem, dla którego nie tylko zrobić @post = Post.last, ponieważ zawsze domyślnie sortuje według klucza podstawowego (zwykle id). czas to w porządku, ale jestem pewien, że istnieje scenariusz, w którym może to powodować problemy (np. ustawianie niestandardowych identyfikatorów w rekordach, zmiany w bazie danych, które mają wpływ na sekwencjonowanie klucza głównego/automatyczne numerowanie itp.). Sortowanie według znacznika czasu created_at zapewnia, że ​​naprawdę otrzymujesz najnowszy rekord).

+9

Upewnij się, że indeksujesz to pole created_at, jeśli używasz tej metody. – jemminger

+1

Nie będę działał w hakowaniu 'before_validation'. – Green

+1

W Railsach 4 można również dodać wiersz 'default_scope {order (created_at:: asc)} do modelu Post, aby upewnić się, że' Post.last' zachowuje się zgodnie z oczekiwaniami. – sambecker

1

próbować, dla modelu o nazwie ModelName:

record = ModelName.last 
+2

Nie uwzględnia to kolejności sortowania dla tabeli. Byłoby to niemożliwe, gdyby używał bazy danych PostgreSQL – jamesc

+1

To by się nie udało ... świetnie. Co zrobiłbyś, aby uniknąć porażki? –

3

Tak, można użyć metody .last

więc jeśli dany model nazywa się post a następnie:

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

Chociaż odpowiedź dmarkow jest technicznie poprawne, trzeba złożyć indeks created_at lub ryzykować coraz wolniejsze zapytanie w miarę wzrostu bazy danych.

Jeśli wiesz, że twoja kolumna "identyfikator" jest automatycznie kluczowym kluczem podstawowym (który prawdopodobnie jest), to po prostu użyj go, ponieważ jest to z definicji indeks.

Ponadto, chyba że AREL jest zoptymalizowany do wybierania tylko jednego rekordu w znalezisku (: ostatnim), istnieje ryzyko, że wybierze WSZYSTKIE rekordy, a następnie zwróci tylko ostatnią, używając metody "ostatniej()" . Bardziej efektywne jest ograniczenie wyników do jednego:

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

lub

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

'@post = Post.order (" created_at "). Last' faktycznie robi to, co trzeba.Wyjście na konsolę to coś w rodzaju "SELECT". ". * FROM" posty "ORDER BY" wpisy "." Created_at "DESC LIMIT 1' – PhilT

2

można uruchomić w kwestii niejednoznaczności korzystających created_at na stole wystarczająco dużym nasileniu ruchu.

np. spróbuj:

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

..has potencjał mają taką samą created_at, który ma tylko 1 sekundę rozmiar. sortowanie zwróci je w określonej kolejności.

lepiej może być przechowywanie wartości mikrotime i sortowanie na tym.

Powiązane problemy