случайная петля с условиями в рельсах - PullRequest
1 голос
/ 04 сентября 2011

У меня есть функция под названием «Обзор», которая позволяет пользователям просматривать произвольные профили. Когда пользователь нажимает кнопку «Обзор», он сразу попадает в профиль пользователя, с которым он НЕ уже дружит. Как должен выглядеть мой контроллер?

Прямо сейчас у меня есть:

  def browse
    @users = User.all.offset(rand(current_user.matches.count))
    @users.each do |user|
      if !current_user.friends.include?(user)
        @user = user
        return
      end
    end
  end

Однако, похоже, это не работает. Любой совет? Похоже, мне плохо с блоками!

Ответы [ 2 ]

2 голосов
/ 04 сентября 2011

Вы можете попробовать что-то вроде этого

def browse
   @user = (User.all - current_user.friends).sample
end

Лучшей версией будет

def browse
   @user = User.where('id not in (?)', current_user.friends.map(&:id))
           .offset(rand(current_user.matches.count)).limit(1)
end

Кроме того, если вы слишком обеспокоены производительностью, вместо использования метода смещения, лучшеиспользуйте камень randumb , чтобы получить случайную запись.Он использует функции базы данных для выбора случайных записей, если таковые имеются.

1 голос
/ 04 сентября 2011

Добавьте дополнительный метод для вашего пользователя, что-то вроде этого:

def random_stranger
    self.class.where(%Q{
        id not in (
            select friend_id
            from friends
            where user_id = ?
    }, self.id).
    order('random()').
    limit(1).
    first
end

Затем в вашем контроллере:

def browse
    @user = current_user.random_stranger
end

Если ваша база данных не знает, как оптимизировать это not in, тогда вы можете заменить его на LEFT OUTER JOIN в сочетании с WHERE friend_id is null.

...