2011-09-04 56 views
1

我有一個稱爲「瀏覽」,允許用戶瀏覽隨機配置文件的功能。當用戶點擊「瀏覽」時,他們立即被帶到一個他們還不是朋友的用戶檔案中。我的控制器應該是什麼樣子?隨機循環與軌道條件

現在我已經得到了:

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 

但似乎並不奏效。有什麼建議?我承認塊壞了,看來!

+0

@mu你的意思是?用戶(id:integer,email:string,encrypted_pa​​ssword:string,reset_password_token:string,reset_password_sent_at:datetime,remember_created_at:datetime,sign_in_count:integer,current_sign_in_at:datetime,last_sign_in_at:datetime,current_sign_in_ip:string,last_sign_in_ip:string,created_at:datetime, updated_at:datetime,login:string,sex:string,birthday:date,zip:string,city:string,state:string,latitude:float,longitude:float,rating_count:integer,score:integer) – goddamnyouryan

回答

2

你可以嘗試這樣的事情

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寶石拿取隨機記錄。如果可用,它使用數據庫特定函數來選擇隨機記錄。在您的控制器然後

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 

+1

如果有百萬用戶 - 'User.all'會將它們全部加載到內存中。 – Zabba

+0

贊同Zabba!再次更新答案... – dexter

1

添加一個額外的方法,以您的用戶,這樣的事情

def browse 
    @user = current_user.random_stranger 
end 

如果你的數據庫不知道如何來優化not in,那麼你可以用LEFT OUTER JOINWHERE friend_id is null組合替換它。

+0

非常感謝!我使用postgres,可以處理'不在'? – goddamnyouryan

+0

@weckersham:PostgreSQL應該可以,'ORDER BY RANDOM()'也可能有問題,但(a)在數據庫中保持這種邏輯是最好的選擇,(b)不要太擔心它,只需將邏輯妥善保存在一個地方(即特定方法),以便在出現問題時可以輕鬆修復它。 –