2014-11-03 82 views
0

我在Rails 4.1應用程序中使用acts_as_taggable_on gem。我正在使用範圍根據標籤或多個標籤進行搜索。當給出多個標籤作爲參數時,我希望搜索只返回包含所有標籤的標籤項目。目前,我已返回的作用域返回包含至少一個標記(tag_a或tag_b或tag_c)的標記項目。我想要一個作用域而不是AND條件(tag_a AND tag_b AND tag_c)。Rails Active Record Query - 多值條件(AND而不是OR)

document_a_tags = ['programming', 'ruby'] 
document_b_tags = ['programming', 'python'] 

class User < ActiveRecord::Base 
    has_many :documents, dependent: :destroy 
    scope :with_fields, proc { |fields| 
    if fields.reject!(&:empty?).present? 
     joins(documents: [{ taggings: :tag }]).where(tags: { slug: fields }) 
    end 
    } 
end 

class Document < ActiveRecord::Base 
    acts_as_taggable 
    belongs_to :user 
end 

目前,如果搜索PARAMS包括programmingruby都document_a和document_b將被退回。我想要的是一個範圍,如果搜索參數包括programmingruby,則只返回document_a。

+0

你試過了嗎:'tagged_with'?例如:'Item.joins(文檔:[{taggings::tag}])。tagged_with(fields)'? – Surya 2014-11-03 09:50:30

+0

@ User089247感謝您的建議。這給了我一個錯誤,雖然標籤是在Document模型上,而不是User模型:'NoMethodError(未定義方法'tagged_with'爲# diasks2 2014-11-03 10:25:48

+0

@ diask2:我沒有把它寫成'User ...'它是'Item..',然而,我們必須理解示例代碼和實際代碼之間的區別,並且使用這個想法來使解決方案有效。 – Surya 2014-11-03 10:42:15

回答

0

鑑於mysql的工作方式,我認爲這是很難在單個活動記錄查詢中完成的。

連接爲與條目連接的每個標記添加一行,並且條件僅在當時應用於一行。也就是說,一行不能被一個條件說明結果中的某些其他行。

我認爲可能會寫一些複雜的遞歸查詢,將不確定數量的列添加到結果中並在其上應用條件。但是我認爲簡單地使用當前範圍,然後在ruby代碼中丟棄沒有所有標籤的條目會容易得多並且性能更高。

編輯: 這可能會在您使用的寶石中完成。看看:

User.tagged_with(["awesome", "cool"], :match_all => true) 
+0

謝謝。但是,這個範圍是在用戶模型,但它是有標籤的文檔模型(用戶has_many:文檔)。因此,如果我嘗試tagged_with我得到了'NoMethodError(未定義方法tagged_with'爲# diasks2 2014-11-03 10:24:35

+0

這只是從他們的文檔複製的一個例子,它必須根據您的設置進行調整 – Albin 2014-11-03 10:30:31

+0

這是應該接受的正確答案 – Fred 2014-11-03 10:41:36