2012-03-22 14 views
5

के माध्यम से स्वच्छ संघरेल 3.2.2 - has_many

एक खेल एक HOME_TEAM और एक AWAY_TEAM है प्रदान करने के लिए कोड refactor करने के लिए कोशिश कर रहा

एक टीम HOME_TEAM या एक AWAY_TEAM

एसोसिएशन के रूप में कई खेल है गेम और टीम के बीच एक सीधा-आगे हैबटम है लेकिन मुझे यह इंगित करने की आवश्यकता है कि गेम के साथ जुड़े दो टीमों में से कौन सी टीम HOME_TEAM है और जो AWAY_TEAM है। मैंने इसे अतिरिक्त फ़ील्ड और एसोसिएशन जोड़कर किया लेकिन यह सूखे की बजाय बहुत गीला है। मुझे पता है कि जवाब में है लेकिन मुझे लगता है कि मस्तिष्क में गिरावट आई है और मुझे इसके चारों ओर अपना सिर नहीं मिल सकता है।

मूल रूप से मैं Game.teams ऐसा करने में सक्षम होना चाहता हूँ और Game.home_team (हो और HOME_TEAM करने के लिए एक टीम सेट) और Game.away_team (हो और AWAY_TEAM करने के लिए एक टीम सेट)

(दोनों टीमों के संग्रह रिटर्न)

इस तरह के एक सरल लग क्वेरी पोज़ देने के लिए क्षमा करें, लेकिन यह सिर्फ मुझे

class Game < ActiveRecord::Base 
    belongs_to :home_team 
    belongs_to :away_team 
    has_and_belongs_to_many :teams 
end 

class HomeTeam < ActiveRecord::Base 
    belongs_to :team 
    has_one :games 
end 

class AwayTeam < ActiveRecord::Base 
    belongs_to :team 
    has_one :games 
end 

class Team < ActiveRecord::Base 
    has_and_belongs_to_many :games 
    has_many :away_teams 
    has_many :home_teams 
end 

से दूर मिला है सभी मदद बहुत सराहना

पीटर

+2

क्या आप वास्तव में होमटेम और एवेटम को अलग-अलग कक्षाएं चाहते हैं? और, वर्तमान में, अलग डीबी टेबल? – Chowlett

+0

नहीं - यह सिर्फ एक बॉज है। मुझे शायद एक games_टेम्स टेबल चाहिए जो home_team बूलियन के साथ मुझे लगता है ... – pshear0

उत्तर

7

जो आप करना चाहते हैं, उसे hatbm के बजाय has_many :through का उपयोग करना चाहिए। अधिक जानकारी के लिए here देखें। संक्षेप में, अच्छी बात यह है कि आप जॉइन टेबल में अन्य चर जोड़ सकते हैं। आपके मामले में, एक बूलियन home_team कहा जाता है।

तो मैं यहां क्या करूँगा। सबसे पहले, एक संघ तालिका बनाने (के बाद से मैं बहुत कल्पना नहीं है, मैं इसे भागीदारी फोन करता हूँ):

create_table :participations, do |t| 
    t.integer :game_id, :null => false 
    t.integer :team_id, :null => false 
    t.boolean :home_team 
end 

आप देख सकते हैं, अपने gamesteams तालिका के विपरीत, इस एक एक आईडी है। और आप इसमें विशेषताओं को जोड़ सकते हैं। फिर, मैं इन मॉडलों का प्रयोग करेंगे:

class Participation < ActiveRecord::Base 
    belongs_to :game 
    belongs_to :team 
end 

class Game < ActiveRecord::Base 
    has_many :participations, :dependent => :destroy 
    has_many :teams, :through => :participations 
end 

class Team < ActiveRecord::Base 
    has_many :participations, :dependent => :destroy 
    has_many :games, :through => :participations 
end 

तो एक खेल की टीमों प्राप्त करने के लिए, आप @game.teams है।

अब, HOME_TEAM और AWAY_TEAM पाने के लिए अपने खेल मॉडल के लिए इन तरीकों जोड़ें:

def home_team 
    self.teams.joins(:participations).where("participations.home_team IS ?", true).first 
end 

def away_team 
    self.teams.joins(:participations).where("participations.home_team IS ?", false).first 
end 

और फिर आप @game.home_team और @game.away_team ऐसा करने में सक्षम हो जाएगा।

पीटर संपादित करें: ठीक है, तो mysql के लिए आप विभिन्न का उपयोग करना होगा जहां बयान:

self.teams.joins (: प्रतिभागियों) .where ("? Participants.home_team =" सच)। सबसे पहले self.teams.joins (: प्रतिभागियों)। कहीं ("प्रतिभागियों.home_team IS NULL")। पहले

मैं या तो "=?", सत्य और "! =?", सत्य का उपयोग कर सकता हूं - या - शून्य नहीं है और आईएस नल

मैं झूठा के लिए लगता है कि तुम इतना तो वहाँ अपनी टीमों स्थापित करने के लिए कम से कम 2 तरीके हैं, where("participants.home_team = ?", false)

ठीक है का उपयोग कर प्रयास करना चाहिए।

  1. आप उपयोगकर्ता चुनते हैं, जिन टीम घर खेल रहा है
  2. आप पहली टीम मान लें घरेलू टीम

आप संख्या 1 के लिए जाना है, तो आप एक रेडियो बटन का उपयोग करना चाहिए यह बताने के लिए है उपयोगकर्ता तय करते हैं। कुछ इस तरह:

<%= label_tag :home, 'Home Team' %><br /> 
<%= label_tag :home_team_1, 'Team 1' %><%= radio_button_tag :home_team, 1 %> 
<%= label_tag :home_team_2, 'Team 2' %><%= radio_button_tag :home_team, 2 %> 

तो अगर params[:home_team] == 1 वाली पहली टीम घरेलू टीम, है अगर params[:home_team] == 2, दूसरी टीम घरेलू टीम है।

आप नंबर 2 के लिए जाना है, तो, आप अपने प्रपत्र में कुछ इस तरह अपने खेल के लिए टीमों में शामिल कर सकता होना चाहिए:

<%= label_tag :name, 'Home Team' %> 
    <%= text_field_tag :name, nil, :name => "home[]" %> 

    <%= label_tag :name, 'Away Team' %> 
    <%= text_field_tag :name, nil, :name => "away[]" %> 
कुछ

तो फिर अपने नियंत्रक में आप कर सकते हैं की तरह

@game = Game.new(params[:game]) 

home = Team.create(params[:home]) 
# or 
home = Team.find_or_create_by_name(params[:home][:name]) 
@game.participations.create(:team_id => home.id, :home_team => true or 1) 

away = Team.find_or_create_by_name(params[:away][:name]) 
@game.participations.create(:team_id => away.id, :home_team => false or 0) 
+0

अशितका - यह बहुत ही आशाजनक लगता है। जैसा कि हम बोलते हैं, मेरे टेस्ट बेड में इमारत बना रहा हूं। अगर यह काम करता है और स्वीकार करता है तो आपको बताएगा। आपकी प्रतिक्रिया के लिए धन्यवाद – pshear0

+0

मैंने अपना प्रश्न संपादित किया और वास्तव में इस बार इसका परीक्षण किया। यह सही तरीके से काम कर रहा है, इसे आज़माएं और बताओ कि यह कैसा चल रहा है! – Ashitaka

+0

हाय अशितका, अभी भी इस समस्या के माध्यम से काम कर रहा है। अपने समाधान का उपयोग करके मैंने माईएसक्ल के साथ मुद्दों में भाग लिया और क्लॉज – pshear0

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