Помогите преобразовать логику Rails 2 Database в Rails 3.1 / PostgreSQL - PullRequest
1 голос
/ 08 августа 2011

Как выбрать одну случайную запись для каждого пользователя, но упорядочить массив по последней записи pr.user.

Если Foo загрузит новую картину, я бы хотел выбрать одну случайную запись из foo.Таким образом, пользователь, загружающий 10 картин, не будет монополизировать все пространство на главной странице, но все равно получит слот в верхней части страницы.

Вот как я это сделал при работе с Rails 2.xна MySQL.

@paintings = Painting.all.reverse
first_paintings = []
@paintings.group_by(&:user_id).each do |user_id, paintings|
  first_paintings << paintings[rand(paintings.size-1)]
end
@paintings = (first_paintings + (Painting.all - first_paintings).reverse).paginate(:per_page => 9, :page => params[:page])

Приведенный выше пример генерирует много SQL-запросов и неправильно оптимизирован.Как бы вы справились с этим, когда Rails 3.1 работает на PostgreSQL?У меня 7000 записей ..

Ответы [ 3 ]

1 голос
/ 08 августа 2011

Вы определенно настроили ассоциацию belongs_to в своей модели Painting, поэтому я бы сделал:

# painting.rb
default_scope order('id DESC')

# paintings_controller.rb
first_paintings = User.includes(:paintings).collect do |user|
  user.paintings.sample
end
@paintings = (first_paintings + Painting.where('id NOT IN (?)', first_paintings)).paginate(:per_page => 9, :page => params[:page])

Я думаю, что это решение приводит к наименьшему количеству запросов SQL и очень читабельно. Не проверено, но я надеюсь, что у вас есть идея.

1 голос
/ 08 августа 2011

@paintings = Painting.all.reverse = @paintings = Painting.order("id desc")

Если вы действительно хотите изменить порядок результирующего набора картин, я бы настроил область действия, а затем просто используйте

Что-то вроде

class Painting < ActiveRecord::Base  
  scope :reversed, order("id desc")
end  

Тогда вы можете использовать Painting.reversed везде, где вам нужно

0 голосов
/ 08 августа 2011

Вы можете использовать динамические искатели:

Painting.order("id desc").find_by_user_id!(user.id)

Предполагается, что ваша таблица Paintings содержит столбец user_id или какой-либо другой способ связать пользователей с картинами, которые, как вам кажется, вы покрыли с момента вызова user_idв вашем исходном коде.Это не случайно, но использование find_all_by_user_id позволит вам вызвать .reverse для массива, если вы все еще хотите, и найти случайную картину.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...