2016-09-16 67 views
0

我有一個模型將數組存儲在名爲'attributes'的表列之一中。因此,3個獨立的記錄可能是這樣的:Rails 4使用Ruby Enumerable使用數組查詢數組

記錄1

MyModel.attributes = {Red, Furry, Stinky} 

記錄2

MyModel.attributes = {Red} 

記錄3

MyModel.attributes = nil 

記錄4

MyModel.attributes = {Blue, Furry, Sweet} 

我想查詢該陣列,用於任何其他陣列,包括零的。結果應返回查詢數組中具有任何屬性的記錄以及屬性列爲零的任何記錄。

query_array = [Blue, Furry] 

這個問題的答案查詢應提供記錄1,記錄3和記錄4 - 再次,它不看的所有

目前,我可以,如果我只是查詢

MyModel.all.select {|m| m.attributes["Furry"] or m.attributes["Blue"] } 
做到這一點

但我希望能夠動態地創建數組,而不是手動編寫m.attributes [「attribute」]。我不知道如何做到這一點,而不需要所有的數組項,我只想要任何數組項和沒有屬性的記錄。

+0

你正在使用什麼類型的數據庫?該列是什麼格式? –

回答

1

您可能不應該調用列attributes,因爲此名稱已用於rails模型中的屬性哈希訪問器。對於低於我的例子改名這tags

一個簡單的解決辦法是檢查nil(總是包括這些記錄),並檢查標籤的交叉點中有任何標籤:

model_1.tags # => ['red', 'furry', 'stinky'] 
model_2.tags # => ['red'] 
model_3.tags # => nil 
model_4.tags # => ['blue', 'furry', 'stinky'] 

search_tags = ['red', 'blue'] 
MyModel.all.select do |model| 
    model.tags.nil? || (model.tags & search_tags).any? 
end 

你可以也寫它作爲一個嵌套循環:

search_tags = ['red', 'blue'] 
MyModel.all.select do |model| 
    model.tags.nil? || model.tags.any? { |tag| search_tags.include?(tag) } 
end 

這一切都在內存中完成,在紅寶石本身。如果您有100_000或1_000_000記錄,則所有這些記錄都從數據庫中提取,實例化並過濾。

因此,根據您的具體要求和您使用的數據庫,您可以找到更簡單/更高性能的解決方案。一些想法:

  • 商店標籤在單獨的表
  • 商店標籤爲逗號分隔字符串,並使用「喜歡」查詢
  • 對Postgres JSON數據類型和查詢功能Postgres提供
+0

謝謝......它實際上不叫屬性,但名稱讓人分心,所以我添加了一個佔位符名稱。不過謝謝你的提醒。關於如何更好地做到這一點的建議....你是對的,這就像標籤。我正在重構... – NothingToSeeHere

-1

你可以試試這個

query_array = [Furry, Blue] 
query_string = query_array.map{|query| "m.attributes[#{query}]" }.join(" || ") 

#=> "m.attributes[Furry] || m.attributes[Blue]" 

MyModel.all.select {|m| eval(query_string) } 

現在,所有你需要做的就是添加更多項目進入query_array

+0

請永遠不要使用'eval'。這是邪惡的,危險的,難以調試,難以理解。 –

+0

忘記添加:並可以發佈安全問題。 –