Rails 3, will_paginate, random, repetición de registros, Postgres, falla de búsqueda

Tengo una base de datos de películas con atributos. Me gustaría devolver un lote consultado de esas películas en orden aleatorio a una plantilla con paginación. Estoy usando will_paginate. Intenté lo siguiente:

<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>

Esto funciona bien, excepto que las películas se repiten de una página a otra. Se han publicado soluciones a este problema.aquí yaquí. Esos enlaces lo explican, porque laaleatorio() Se reinicia la semilla de una página a otra, no hay coherencia yCOMPENSAR se vuelve inútil. Ofrecen grandes soluciones para los usuarios de MySQL, ya querand (n) la función toma una semillan. Postgres, sin embargo, no hace esto. Tienes que declararsetseed (n) enSELECCIONAR antes de emitiraleatorio() enORDEN.

Así que intenté la forma postgres para establecer la semilla:

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

Curiosamente, eso devolvió objetos de película sin ningún atributo. Lo siguiente fue sacado de la plantilla:

ActiveModel :: MissingAttributeError en Movies # action

atributo que falta: some_movie_attribute

Depuré esto y, una vez que la pila alcanzó action_controller / metal, @movies contenía:

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

Ese número de objetos de Película (18) corresponde al número de películas devueltas de la consulta.

También probé lo siguiente para ver sisetseed (n) fue el problema al eliminar el método de orden aleatorio:

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

Esto devolvió los mismos objetos de película sin atributos como se describe arriba. Así que parece quesetseed (n) Es de hecho el problema.

He intentado un par de soluciones, como:

<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>

Eso también devolvió páginas con repetición de películas. Pensé que esto era porque la paginación necesitaba los objetos para ser ordenados poralguna cosa, y no puedes poner semillas en Array # shuffle. Así que intenté escribir mi propio código de aleatorización que almacenaría temporalmente una identificación para ordenar en los objetos de la película. (Por favor disculpe el código descuidado):

<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>

Eso todavía producía repetición de películas en diferentes páginas. En este punto, me doy cuenta de que will_paginate no asimila lo que has ordenado antespaginar se llama. Así que intenté esto:

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

Eso todavía se repite los registros.: orden -> 'rand_id' se ignora porque:orden solo importa cuando se trata de objetos ActiveRecord, no de arreglos.

Asi quesetseed (n) parece ser mi única esperanza para lograr registros aleatorios no repetitivos usando will_paginate. ¿Algunas ideas?

¡Gracias!

Respuestas a la pregunta(2)

Su respuesta a la pregunta