2010-02-04 13 views
6

यह मेरा मॉडल है:कैसे एक has_many से एक पंक्ति संख्या प्राप्त कर सकते हैं: के साथ संबंधों के माध्यम से: uniq => true

class Tag < ActiveRecord::Base 
    # id, name 
    has_many :taggings 
end 

class Tagging < ActiveRecord::Base 
    # id, tag_id, owner_id, target_type, target_id 
    belongs_to :tag 
    belongs_to :owner, :class_name => 'User' 
    belongs_to :target, :polymorphic => true 
    validates_uniqueness_of :tag_id, :scope => [ :target_id, :target_type, :owner_id ] 
end 

class Asset < ActiveRecord::Base 
    # id, owner_id, title, type, etc 
    belongs_to :owner, :class_name => 'User' 
    has_many :taggings, :as => :target 
    has_many :taggers, :through => :taggings, :source => :owner, :uniq => true 
    has_many :tags, :through => :taggings, :uniq => true 
end 

class User < ActiveRecord::Base 
    # id, name, email, etc 
    has_many :assets, :foreign_key => 'owner_id' 
    has_many :my_taggings, :class_name => 'Tagging', :foreign_key => 'owner_id' 
    has_many :my_tags, :through => :my_taggings, :source => :tag, :uniq => true 
    has_many :taggings, :as => :target 
    has_many :taggers, :through => :taggings, :source => :owner, :uniq => true 
    has_many :tags, :through => :taggings, :uniq => true 
end 

संबंधों के सभी काम कर रहे हैं, लेकिन मैं किसी अतिरिक्त शर्त है कि मैं नहीं कर सकता

एसेट वर्ग

has_many :tags, :through => :taggings, :uniq => true 

Asset.find बुला में इस संबंध पर विचार करें: के लिए समाधान खोजने के (: पहले) .tags का टैग एक सरणी रिटर्न की उम्मीद के रूप में, लेकिन प्रत्येक टैग एक को रोकने के लिए के लिए मैं की जरूरत है गिनती विशेषता दर्शाती है कि पंक्ति कितनी बार दिखाई देगी यदि: uniq => सत्य निर्दिष्ट नहीं किया गया था।

उदाहरण के लिए। एक से अधिक उपयोगकर्ता एक ही टैग को एक ही टैग पर लागू कर सकते हैं। मैं टैग नाम और उपयोगकर्ताओं को लागू करने वाले लोगों की संख्या प्रदर्शित करना चाहता हूं।

उत्तर

5

यह वही करना चाहिए जो आप चाहते हैं।

has_many :tags_with_count, :source => :tag, :through => :taggings, 
    :group => "tags.id", :joins => :taggings, 
    :select = "tags.*, COUNT('taggings.id') AS frequency" 

पंक्तियों के संदर्भ में लौटे: समूह =>: आईडी के रूप में एक ही सेट वापस आ जाएगी: uniq => true, लेकिन यह भी आप गणना आप चाहते हैं प्रदर्शन करने के लिए अनुमति देगा। यह कथन अधिक श्रम गहन है: uniq => सत्य, इसलिए मैंने इसे एक अलग नाम दिया है जिससे आप चुन सकते हैं कि अद्वितीय समूह को उनके समूहबद्ध गणनाओं के साथ, या केवल अद्वितीय टैग की सूची प्राप्त करना है या नहीं।

उपरोक्त कथन वापस किए गए रिकॉर्ड में आवृत्ति विशेषता जोड़ देगा। Method_missing के जादू के माध्यम से, आप @ tag.frequency के साथ उस तक पहुंच सकते हैं।

उपयोग:

@tags = @asset.tags_with_count 
@tags.each{|tag| puts [tag.id, tag.name. tag.frequency].join "\t"} 

प्रिंट होगा आईडी, नाम, और @asset के लिए प्रत्येक टैग की घटनाओं की संख्या।

+0

अच्छा। वहां बहुत अच्छी जानकारी है! –

+0

काफी काम नहीं करता है। मुझे ड्रॉप करना पड़ा: joins =>: टैगिंग्स और एक जोड़ें: स्रोत =>: टैग। निम्नलिखित आवश्यकतानुसार बिल्कुल काम करता है - has_many: tag_with_count,: through =>: टैगिंग्स:: स्रोत =>: टैग,: समूह => "टैग.आईडी",: चयन => "टैग। *, COUNT (\" टैगिंग .id \ ") एएस फ्रीक्वेंसी" ..... मुझे आपकी सहायता के बिना यह नहीं मिला होता, इसलिए मैं वैसे भी आपका जवाब स्वीकार कर रहा हूं। आप के बारे में अच्छा होगा हालांकि आपका जवाब संपादित कर सकता है। –

+0

इसके बारे में क्षमा करें। मुझे नेस्टेड उद्धरण पकड़े गए होंगे, और एक स्रोत विकल्प की आवश्यकता है। उन छोटी त्रुटियों को ठीक करने के लिए समाधान आह संपादित किया गया है। – EmFi

संबंधित मुद्दे