Ich habe eine Datenbank von Filmen mit Attributen. Ich möchte eine abgefragte Menge dieser Filme in zufälliger Reihenfolge an eine Vorlage mit Paginierung zurückgeben. Ich benutze will_paginate. Ich habe folgendes versucht:Rails 3, will_paginate, zufällige, wiederholte Datensätze, Postgres, setseed Fehler
## MoviesController
movies = Movie.get_movies(query_string) # a method in Movie model that takes in
# a query_string and fetches movies
# with user-set params
@movies = movies.order('random()').page(params[:page]).per_page(16)
Dies funktioniert gut, außer Filme werden von Seite zu Seite wiederholt. Lösungen für dieses Problem wurden veröffentlicht here und here. Diese Links erklären, dass Random() Seed von Seite zu Seite zurückgesetzt wird, gibt es keine Konsistenz und OFFSET wird unbrauchbar gemacht. Sie bieten großartige Lösungen für MySQL-Benutzer, da die rand (n)-Funktion einen Seed n übernimmt. Postgres tut dies jedoch nicht. Sie haben setseed (n) in SELECT vor random() in ORDER Ausgabe zu erklären.
So habe ich versucht, den Postgres Weg, um die Samen zu setzen:
@movies = movies.select('setseed(.5)').order('random()').page(params[:page]).per_page(16)
Seltsamerweise, die Film mit absolut keine Attribute Objekte zurückgegeben. Das Folgende wurde aus der Vorlage erhöht:
ActiveModel :: MissingAttributeError in Filme # Aktion
fehlende Attribut: some_movie_attribute
ich dies und debuggt, sobald der Stapel action_controller erreicht/Metall, @movies enthalten:
[#<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >]
Die Anzahl der Filmobjekte (18) entspricht der Anzahl der Filme, die von der Abfrage zurückgegeben werden.
Ich habe versucht, auch die folgenden zu sehen, ob setseed (n) das Problem Verfahren durch Entfernen der zufälligen Reihenfolge war:
@movies = movies.select('setseed(.5)').page(params[:page]).per_page(16)
Dies ergab die gleichen Nicht-Attribut Filmobjekte wie oben verlegt werden. So scheint es, dass setseed (n) tatsächlich das Problem ist.
habe ich versucht, ein paar Workarounds, wie:
# MoviesController
movies = Movie.get_movies(query_string)
shuf_movs = movies.shuffle ## effectively turns shuf_movs into an array
@movies = shuf_movs.paginate(:page => params[:page], :per_page => 16)
die auch Seiten mit sich wiederholenden Filmen zurück. Ich dachte, das sei deshalb, weil die Paginierung die Objekte benötigt, die von etwas bestellt werden sollen, und Sie können in Array # shuffle keine Seeds festlegen. Also habe ich versucht, meinen eigenen Randomisierungscode zu schreiben, der vorübergehend eine ID speichern würde, um in den Movie-Objekten geordnet zu werden. (Bitte entschuldigen Sie den schlampigen Code):
# Movie model
attr_accessor :rand_id
# MoviesController
movies = get_movies(query_string)
movies_count = movies.count
r = Random.new
nums = []
rand_movs = []
id = 1
while nums.count != movies_count
num = r.rand(0..movies_count - 1)
if !(nums.include?(num))
movie = movies[num]
movie.rand_id = id
rand_movs << movie
nums << num
id += 1
end
end
@movies = rand_movs.sort_by { |a| a.rand_id }.paginate(:page => params[:page], :per_page => 16)
Das produzierte immer noch das Wiederholen von Filmen in verschiedenen Seiten.An diesem Punkt merke ich, dass wil_paginate nicht berücksichtigt, was Sie sortiert haben, bevor paginate aufgerufen wird. Also habe ich das versucht:
@movies = rand_movs.paginate(:order => 'rand_id', :page => params[:page], :per_page => 16)
Das wiederholt immer noch Datensätze. : order -> 'rand_id' wird ignoriert, weil : order nur dann von Bedeutung ist, wenn Sie mit ActiveRecord-Objekten, nicht mit Arrays arbeiten.
Also setseed (n) scheint meine einzige Hoffnung für das Erreichen von randomisierten sich nicht wiederholenden Aufzeichnungen mit will_paginate zu sein. Irgendwelche Ideen?
Danke!
Die select gibt die Spalten mit Saatgut in der Abfrage, und Sie haben keine angegeben, nur den Seed. Nicht sicher, ob es funktioniert, aber versuchen Sie es: '.select ('*, setseed (1)')' – Matzi