2011-02-06 13 views
5

मुझे एक ऐसा उत्तर मिल रहा है जो उपयोगकर्ता नामों की एक सरणी (अधिमानतः) नामित_स्कोप या उपयोगकर्ता मॉडल पर क्लास विधि के माध्यम से लौटाएगा जो कुछ हेरफेर करता है। उपयोगकर्ताओं और झगड़े:नाम_स्कोप के माध्यम से वस्तुओं की वापसी सरणी - has_many ... belong_to एसोसिएशन; यूनियन सभी क्वेरी

आगे की हलचल के बिना

तो ...

मैं दो तालिकाओं की है। (: झगड़े,: has_many foreign_key => 'challenger_id या challengee_id')

  • उपयोगकर्ता कई झगड़े है
  • लड़ाई उपयोगकर्ता के अंतर्गत आता है (belongs_to: चैलेंजर,: CLASS_NAME => 'उपयोगकर्ता' ... belongs_to: challengee ,: CLASS_NAME => 'उपयोगकर्ता')

लड़ाई चिंता का निम्न स्तंभ हैं:)

  • challenger_id (FK user_id
  • chall engee_id (FK user_id)
  • challenger_won (बूलियन)

आप देख सकते हैं, एक उपयोगकर्ता एक चुनौती या एक challengee हो सकता है, लेकिन दोनों नहीं।

  • यदि उपयोगकर्ता एक चुनौतीपूर्ण और challenger_won = true है, तो इसे जीत माना जाता है।
  • यदि उपयोगकर्ता एक चुनौतीपूर्ण और challenger_won = false है, तो इसे एक जीत माना जाता है।
  • यदि challenger_won = null, तो बस इसे अवहेलना करें।

मैं एक कच्चे एसक्यूएल बयान है कि एक लड़ाकू विशेषता (user_id) में सर्वाधिक जीत हासिल आधार पर वर्गीकृत किया देता है विशेषता:

SELECT a.fighter, COUNT(*) AS wins 
    FROM (SELECT challenger_id AS fighter 
      FROM fights 
     WHERE challenger_won = TRUE 
     UNION ALL 
     SELECT challengee_id AS fighter 
      FROM fights 
     WHERE challenger_won = FALSE 
     ) AS a 
GROUP BY a.fighter; 

तो यह जानकारी दी, मैं कैसे उपयोगकर्ता ऑब्जेक्ट की श्रृंखला के माध्यम से लौट सकते हैं (अधिमानतः) एक नाम_स्कोप या उपयोगकर्ता मॉडल पर एक क्लास विधि के माध्यम से जो कुछ हेरफेर करता है?

+0

अपने 'fights' तालिका में' challenger_won' कॉलम बदल रहा है, एक 'winner_id' (FK user_id) कि खोज कर देगा पर विचार एक बहुत क्लीनर जीत । उसके बाद आपके पास 'has_many: wins,: class_name =>' Fight ',: foreign_key =>' winner_id'' हो सकता है जो आपको कुल उपयोगकर्ता – joshnuss

उत्तर

4

मुझे लगता है कि आप में से आप क्वेरी परिणाम से बनाना कुछ इस तरह की कोशिश कर सकते हैं:

class User 
    named_scope :winners, 
     :select => 'users.*, COUNT(fight.id) AS wins', 
     :join => :fights, 
     :conditions => ['(fights.challenger_id = user_id AND fights.challenger_won = TRUE) OR (fights.challengee_id = user_id AND NOT fights.challenger_won = FALSE)'] 
     :group => 'user_id' 
end 

हालांकि, कैशिंग puposes के लिए, आप उपयोगकर्ता मॉडल के लिए एक win_count क्षेत्र को जोड़ने पर विचार कर सकते हैं। यदि आप किसी लड़ाई के विजेता के लिए एक सेटटर विधि बनाते हैं, तो आप उस क्षण में win_count को उस समय बदल सकते हैं जब यह बदल जाता है।

+0

आह खोजने के लिए 'user.wins.count' करने की अनुमति देगा, यह सही है! विश्वास नहीं कर सकता कि मैंने सिर्फ उपयोगकर्ता मॉडल को काउंटर जोड़ने के बारे में नहीं सोचा था ... यह निश्चित रूप से सबसे अच्छा तरीका है ... धन्यवाद – keruilin

0

या बिना, में शामिल होने के (mysql विशिष्ट)

class User 
    named_scope :winners, 
    :select => 'if(challenger_won = FALSE,challenger,challengee) as winner,COUNT(id) AS wins ', 
    :group => 'user_id' 
end 
संबंधित मुद्दे