2013-03-08 13 views
7

Próbuję utworzyć relację has_many through z wieloma źródłami. Na przykład gra ma numer home_team i away_team, a turniej ma wiele gier.has_many through multiple sources

Jaki jest najlepszy sposób na zdobycie wszystkich drużyn w turnieju za pomocą relacji has_many through games.

Teraz mój kod wygląda następująco:

class Tournament 
    has_many :teams, :through => :games, :source => :home_team, :uniq => true 
end 

ale chcę jakiś sposób, aby działać jak:

class Tournament 
    has_many :teams, :through => :games, :source => [:home_team, :away_team], :uniq => true 
end 

EDIT: wiele do wielu relacji nie jest mój problem. Czy istnieje dobry sposób, aby wszystkie drużyny w turnieju przyjęły strukturę w następujący sposób.

class Game 
    has_and_belongs_to_many :tournaments 
    belongs_to :home_team, :class_name => Team, :foreign_key => :home_team_id 
    belongs_to :away_team, :class_name => Team, :foreign_key => :away_team_id 
end 

class Tournament 
    has_and_belongs_to_many :games 
end 

Czy istnieje sposób na wykonanie Tournament.teams?

+1

miał podobny problem i skończyło się zmienia mój schemat aby go obejść, ale jedna opcja Patrzyłem na to metoda z użyciem '.merge' http: // stackoverflow.com/questions/11486027/merge-results-from-two-ma-wiele-skojarzeń-z tym samym-modelem Edycja: Myśląc o tym więcej, założę się, że sposób robienia szyn jest dziedziczeniem pojedynczego stołu, gdzie w domu i gry wyjazdowe mają nadrzędną abstrakcyjną klasę 'Game', która zapewnia tabelę złączeń. Spróbuję tego następnym razem :) – thebenedict

Odpowiedz

4

Po spędzeniu trochę czasu na szukaniu wbudowanego rozwiązania, właśnie skończyłem pisać niestandardowe zapytanie zwane zespołami w grach. Łączy zespoły z grami dwa razy w drużynie_1 i drużynie_2 i sprawdza, czy którakolwiek z nazw identyfikatorów gry znajduje się w jednym z tych dwóch połączeń.

To rozwiązanie nie jest świetne, ponieważ wymaga wielu pytań (jednym z nich jest po prostu ogromna lista wszystkich identyfikatorów gier), ale spędziłem dużo czasu próbując wymyślić inny sposób i nie mogłem. Przynajmniej w ten sposób działa.

Chciałbym nauczyć się lepszego sposobu.

Kod wewnątrz gier:

def self.teams 
    joined_tables = Team.joins(:home_team).joins(:away_team) 
    joined_tables.where('games.id in (?) or away_team_games.id in (?)', 
        select(:id), select(:id)).uniq 
end 
-3

określenie modeli tak:

class Tournament 
    has_many :games 
    has_many :teams, :through => :games 
end 

class Game 
    belongs_to :torunament 
    belongs_to :team 
end 

class Team 
    has_many :games 
    has_many :tournaments, :through => :games 
end 

a następnie wywołać w sterowniku, czy gdziekolwiek:

tournament.teams 

EDIT:

można zdefiniować scope dla tego rodzaju problemu w was Tournament Model. Jest to bardziej podobne do niestandardowych zapytań, a jest obsługiwane po kolei po wyjęciu z pudełka. A przynajmniej nie pamiętam w tej chwili.

możesz sprawdzić, jak z nich korzystać.

http://guides.rubyonrails.org/active_record_querying.html http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/scope http://ablogaboutcode.com/2011/02/19/scopes-in-rails-3/

można zbudować kwerendę, która będzie uzyskać wszystkie zespoły. Możesz utworzyć dowolne zapytanie.

+1

Gra ma tylko jeden zespół w tym przykładzie lub czegoś brakuje? –

+0

ouh, tak, masz absolutną rację. Szybko to przeoczyłem. dzięki za wskazanie mi. – Aleks

+0

Lubię, gdy ktoś kładzie "-1" i nie ma po temu powodu. Gdzie akceptowane rozwiązanie ma brzydkie zapytanie niestandardowe. Horay. – Aleks

Powiązane problemy