2012-09-27 43 views
1

給定一個對象如聯繫人:給定一個對象形成一個包含100個項目的查詢。如何在無需重新查詢數據庫的對象中找到項目?

Contact.rb (id, fname, lname, key_tag) 
@contacts = Contacts.where(:user_id => @user.id) 

鑑於@contacts回來了記錄1000在一個數據庫查詢。然後,我如何才能獲取/查看@contacts中是否存在匹配給定'key_tag'的對象。

我想:

@contacts.where(:key_tag => 'def12') 

但是,再次查詢這也正是我想避免什麼數據庫。想法?由於

+0

'@contacts = Contacts.where(:user_id => @ user.id)'產生一個ActiveRelation對象,此時不應該執行查詢。 因此,你的codesample應該只做一個查詢。 – Deradon

回答

0

您可以使用Enumerable find method

@contacts.find {|c| c.key_tag == 'def12'} 
+0

查找速度比選擇快嗎? – AnApprentice

+0

不能保證,但它們本質上不同。當'where'查詢數據庫時,'find'可以處理內存中的對象,並且不會重新查詢數據庫。 –

+1

'select'將返回所有匹配元素的數組,'find'就是第一個這樣的元素。 – MrTheWalrus

0

嘗試Enumerable#find_all

@contacts.find_all {|a| a[:key_tag] == 'def12'} 

或者,如果你想只找到第一個(因爲key_tag是唯一的)

@contacts.find {|a| a[:key_tag] == 'def12'} 

是一定要:

include Enumerable 
1

你有什麼關係。因此,添加另一個用於更改關係並查詢數據的地方。它應該被延遲加載。因此,在你的代碼

Contact.rb (id, fname, lname, key_tag) 
@contacts = Contacts.where(:user_id => @user.id) 

如果你不碰@contacts,它甚至不應該打在DB。但是一旦您嘗試從中獲取數據,它就會被執行並返回數據。如果你要顯示所有這些,你可以使用像#all這樣的東西將它們作爲數組返回,然後使用Array#select來搜索它。根據系統和/或數據庫的速度,DB可能會更有效率地進行選擇。

@contacts = Contacts.where(:user_id => @user.id).all 
@contacts_with_key = @contacts.select { |c| c.key_tag == 'def12' } 
+0

謝謝,我試過選擇,它非常慢。查找速度提高了4倍。不知道爲什麼這是... – AnApprentice

+0

找到只返回1個元素,並找到它後退出。所以根據數據和所述元素的位置,它們可以運行相同的速度(元素是列表中的最後一個元素)。或者真的很快(元素是第一個)。但是,如果只需要第一個元素,那麼找到你需要的,如果你需要所有的元素(IE多鍵,然後選擇可能收集)。但數據庫仍然可能更快取決於表/索引等。 – Doon

相關問題