2011-10-20 78 views
33

我知道「belongs_to的:通過」是無效的,它只是我試圖表達我想達到的目標,只是我承擔片刻...如何設置一種「belongs_to:through」而不設置直接的belongs_to?

這是我得到:

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 

現在,爲了做一個「棒球卡片」視圖的形式,我需要:

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

那麼,有沒有一種方法來設置一個「belongs_to的:通過」直接從訪問「division.name」 'players_controller'沒有'團隊'。字首 ??我必須訪問很多從'player'到'division'的列,所以尋找一種方法來獲得對這些列的「直接」訪問。

一種選擇是在'players'表中包含'division_id'列,但我被告知它會違反關係數據模型,因爲如果數據選擇功能不是妥善處理(例如,玩家A位於A組的A隊,但玩家A的division_id列設置爲B組)。

是否有可能產生「符號鏈接」 '師'現在指的是'team.division',而'league'現在指的是'team.division.league'??

或者,是每次使用完整路徑的唯一真實選項?

希望有人能幫忙。

BR, 喬納斯

+3

嗨喬納斯,請選擇馬特·史密斯的答案正確的,因爲這是一個更優雅的方式。 – emrass

回答

61

使用委託。

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

    delegate :league, to: :division 
end 

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

+1

這是最好的方法,應該選擇而不是blackbird07。 – Jazz

+2

我是aggree! <滿足註釋長度限制的文本> – emrass

+5

這很優雅,但您需要爲對象樹中的每個級別執行一次查詢。所以如果你只需要頂級對象,可以將它打包在一個SQL查詢中。會有後續的c查詢,但仍然只有一個傳輸'rails - (查詢) - >數據庫 - (結果) - > rails'。不幸的是,我不知道用軌道查詢界面做熱門。有誰知道? – pablo

7

您可以在您的播放器模型中定義一個輔助方法:

def division 
    team.division 
end 

def league 
    team.division.league 
end 

當然,這僅涉及到代碼的可讀性,不影響數據庫的形式涉及的查詢。如果你的語句生成多個SQL查詢,但你只想要一個,檢查出.include選擇在這裏:Rails Guides - Active Record Query Interface

+0

謝謝,這似乎是訣竅:o) –

7

您可以嘗試在模型類

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

不,你不應該這樣做。 has_one關係通過外鍵建議另一個模型中的belongs_to關係。但是'Division'不是'belongs_to:team',而是'has_many:teams',這意味着Team'belongs_to:division'。馬特史密斯說得很對:你也可以在Player類中使用這個邏輯:'delegate:division,:to =>:team'。 –

+3

我同意你 - 對於Rails的當前狀態。但我想知道爲什麼沒有belongs_to:through。 – Dogweather

+2

O.o!這適用於最少數量的查詢。我認爲應該有'belongs_to:通過'!而且你的解決方案緩存'division'查詢的結果。 – pablo

相關問題