Rails 3, will_paginate, random, wiederholte Datensätze, Postgres, Setseed-Fehler

Ich habe eine Datenbank mit Filmen mit Attributen. Ich möchte einen abgefragten Stapel dieser Filme in zufälliger Reihenfolge an eine Vorlage mit Paginierung zurückgeben. Ich benutze will_paginate. Ich habe folgendes versucht:

<code>## 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)
</code>

Dies funktioniert gut, außer dass Filme von Seite zu Seite wiederholt werden. Lösungen für dieses Problem wurden veröffentlichtHier undHier. Diese Links erklären das, weil diezufällig() Startwert wird von Seite zu Seite zurückgesetzt, es gibt keine Konsistenz undOFFSET wird unbrauchbar gemacht. Sie bieten großartige Lösungen für MySQL-BenutzerRand (n) Funktion nimmt einen Samenn. Postgres tut dies jedoch nicht. Sie müssen erklärenSaatgut (n) imWÄHLEN vor der Ausstellungzufällig() imAUFTRAG.

Also habe ich den Postgres-Weg ausprobiert, um den Samen zu setzen:

<code>@movies = movies.select('setseed(.5)').order('random()').page(params[:page]).per_page(16)
</code>

Seltsamerweise gab das Movie-Objekte mit absolut keinen Attributen zurück. Folgendes wurde aus der Vorlage hervorgehoben:

ActiveModel :: MissingAttributeError in der Aktion Movies #

fehlendes Attribut: some_movie_attribute

Ich habe dies getestet und als der Stack action_controller / metal erreichte, enthielt @movies:

[#<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >, #<Movie >]

Diese Anzahl von Filmobjekten (18) entspricht der Anzahl von Filmen, die von der Abfrage zurückgegeben wurden.

Ich habe auch Folgendes versucht, um zu sehen, obSaatgut (n) war das Problem beim Entfernen der Zufallsreihenfolge:

<code>@movies = movies.select('setseed(.5)').page(params[:page]).per_page(16)
</code>

Dies gab die gleichen Movie-Objekte ohne Attribute zurück, wie oben beschrieben. So scheint es dasSaatgut (n) ist in der Tat das Problem.

Ich habe ein paar Workarounds ausprobiert:

<code># 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)
</code>

Das brachte auch Seiten mit sich wiederholenden Filmen. Ich dachte, das lag daran, dass bei der Paginierung die Objekte bestellt werden musstenetwas, und Sie können in Array # shuffle keine Startwerte festlegen. Also habe ich versucht, meinen eigenen Zufallscode zu schreiben, in dem vorübergehend eine zu bestellende ID in den Movie-Objekten gespeichert wird. (Bitte entschuldigen Sie den schlampigen Code):

<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)
</code>

Das brachte immer noch sich wiederholende Filme auf verschiedenen Seiten hervor. An diesem Punkt wird mir klar, dass will_paginate nicht das aufnimmt, wonach Sie zuvor sortiert habenpaginieren wird genannt. Also habe ich Folgendes versucht:

<code>@movies = rand_movs.paginate(:order => 'rand_id', :page => params[:page], :per_page => 16)
</code>

Das wiederholt immer noch Aufzeichnungen.: order -> 'rand_id' wird ignoriert weil:Auftrag Dies ist nur wichtig, wenn Sie mit ActiveRecord-Objekten arbeiten, nicht mit Arrays.

SoSaatgut (n) Scheint meine einzige Hoffnung zu sein, mit will_paginate randomisierte, sich nicht wiederholende Datensätze zu erzielen. Irgendwelche Ideen?

Vielen Dank!

Antworten auf die Frage(2)

Ihre Antwort auf die Frage