2011-10-20 12 views
33

znam „belongs_to: poprzez” nie jest poprawny, to tylko moja próba wyrażenia tego, co chcę osiągnąć, tylko pokrywa się ze mną na chwilę ...Jak ustawić rodzaj "belongs_to: through" bez ustawienia bezpośredniego belongs_to?

To jest to, co mam:

class League 
    has_many :divisions 
end 

class Division 
    belongs_to :league 
    has_many :teams 
end 

class Team 
    belongs_to :division 
    has_many :players 
end 

class Player 
    belongs_to :team 
end 

teraz, w celu dokonania „karta” baseball widoku formularza, muszę:

name 
team.name 
team.division.name 
team.division.league.name 

Więc, czy jest jakiś sposób, aby skonfigurować „belongs_to: poprzez” bezpośredni dostęp „division.name” z "players_controller" bez "zespołu". prefiks ?? Muszę uzyskać dostęp do wielu kolumn od "gracza" do "podziału", więc szukam sposobu na uzyskanie "bezpośredniego" dostępu do tych kolumn.

Jedną z opcji jest dodanie kolumny 'division_id' w tabeli 'players', ale powiedziano mi, że złamałoby to relacyjny model danych, ponieważ pozwoliłoby to na niespójność, gdyby funkcja wyboru danych nie była poprawnie obsłużony (np. gracz A jest w drużynie A, która jest w dziale A, ale gracz A ma swoją kolumnę division_id ustawioną na podział B).

Czy można utworzyć "dowiązanie symboliczne", np. "podział" odnosi się teraz do "team.division", a "liga" odnosi się teraz do "team.division.league" ??

Czy jest to jedyna prawdziwa opcja użycia pełnej ścieżki za każdym razem?

Mam nadzieję, że ktoś może pomóc.

Br Jonas

+3

Cześć Jonas, wybierz odpowiedź Matt Smith jako prawidłowa, ponieważ jest to bardziej eleganckie podejście. – emrass

Odpowiedz

61

Używaj delegata w klasie modelu.

class Team < ActiveRecord::Base 
    belongs_to :division 
    has_many :players 

    delegate :league, to: :division 
end 

referencyjny: http://api.rubyonrails.org/classes/Module.html#method-i-delegate

+1

To jest najlepsze podejście i powinno zostać wybrane zamiast blackbird07. – Jazz

+2

I aggree! emrass

+5

Jest to eleganckie, ale musisz wykonać jedną kwerendę dla każdego poziomu w drzewie obiektów. Więc jeśli potrzebujesz tylko najwyższego obiektu, możliwe jest spakowanie go w jednym zapytaniu SQL. Pojawią się kolejne zapytania ofc, ale wciąż tylko jeden transfer 'rails - (zapytanie) -> database - (result) -> rails'. Niestety nie wiem, jak to zrobić z interfejsem zapytań o szyny. Ktokolwiek wie? – pablo

7

Można zdefiniować metody pomocnika w modelu odtwarzacza:

def division 
    team.division 
end 

def league 
    team.division.league 
end 

Oczywiście odnosi się to tylko do odczytu kodu i nie wpływa na formę bazy danych związane z tym zapytania. Jeśli oświadczenie generuje wiele zapytań SQL, ale chcesz tylko jednego, sprawdź opcję tutaj .include: Rails Guides - Active Record Query Interface

+0

Dzięki, wydaje się, że to wystarczy: o) –

7

Możesz spróbować

 
    class Player 
     belongs_to :team 
     has_one :division, :through => :team 
    end 
+2

Nie, nie powinieneś tego robić. Relacja has_one sugeruje relację belongs_to w drugim modelu za pomocą klucza obcego. Ale 'Division' nie' belongs_to: team', it' has_many: teams', co oznacza Team 'belongs_to: division'. Matt Smith ma rację: możesz również użyć tej logiki w klasie Gracza: 'delegate: division,: to =>: team'. –

+3

Zgadzam się z Państwem - za obecny stan Rails. Ale zastanawiam się, dlaczego nie ma żadnego elementu belongs_to: through. – Dogweather

+2

O.o! Działa to z minimalną liczbą zapytań. Myślę, że powinno być 'belongs_to: through'! Ponadto twoje rozwiązanie buforuje wynik zapytania 'division'. – pablo

Powiązane problemy