2012-03-14 8 views

Odpowiedz

19

Zawsze możesz dodać .order('random()') do relacji:

ar = Model.where(...).where(...).order('random()') 

można nawet dodać, że w zakresie:

class Model < ActiveRecord::Base 
    scope :randomize, order('random()') 
end 

Jest kilka rzeczy, o których należy pamiętać f:

  1. PostgreSQL i SQLite random() stosowanie, MySQL używa rand(), nie jestem pewien o innych baz danych.
  2. może być dość kosztowna w bazie danych, więc nie chcesz jej używać, chyba że twoje klauzule WHERE (tj. .where) ograniczą rozmiar zestawu wyników, do którego będziesz stosować ORDER BY random().
  3. .limit zostaną zastosowane po zlecenia przez tak x.limit(n).order('random()') zastosuje BY wszystkim x a następnie zastosować limit(n) po sortowaniu. Tutaj pojawia się ostrzeżenie w (2).
+0

Czy jest inny i/lub ważny (w odniesieniu do wydajności), jeśli zaznaczę 'x.limit (n) .order (" losowy() ")' lub 'x.order ('losowy()'). Limit (n) '? Oznacza to, że te dwa stwierdzenia są równe? – Backo

+0

@Backo: To jest to samo. Wszystkie rzeczy związane z relacjami AR po prostu budują zapytania SQL po kawałku, więc rzeczywista kolejność, w jakiej się dzieje, zależy wyłącznie od tego, jak działa baza danych (to znaczy SQL). Dlatego nie chcesz '.order ('random()')', chyba że masz małą tabelę lub twoje '.where()' s ograniczyć zestaw wyników do małego zestawu wierszy i dlaczego zawarłem punkt (3). –

+1

* BTW *: Ile rekordów uważa się za "mały zestaw"/"mały stolik"? – Backo

0

co z Client.first.users.sample?

+0

Masz rację, ale możesz zwrócić "ActiveRecord :: Relation" (nie Ruby Array)? – Backo

0

Zważywszy, że Store.items jest has_many relacja, można zrobić

a = store.items.all.shuffle 
+0

W tej chwili nie mogę "spróbować"/"uruchomić" twojego kodu ... tak, czy metoda 'shuffle' zwraca 'ActiveRecord :: Relation'? – Backo

+0

@Backo Nie, to będzie tablica. – Baldrick

+1

@ Backo Jestem ciekawy, dlaczego musisz zachować go w "ActiveRecord :: Relation"? – Baldrick