2011-07-19 59 views
1

我試圖找到爲團隊/成員/人員定義模型的最佳方式,其中一個人可以成爲許多團隊的成員,並且團隊可以有許多成員。與「成員」關係一起是該人爲團隊填補的位置。一支球隊也應該有一名主教練和一名助理教練。一個人可以成爲不止一個團隊的頭部/助理教練。使用Rails與has_many進行正確建模:through和belongs_to

下面是我目前(徒勞的)嘗試:

class Team < ActiveRecord::Base 
    has_many :members 
    has_many :people, :through => :members 
    belongs_to :head_coach :class => 'Person' 
    belongs_to :assistant_coach :class => 'Person' 
end 

class Person < ActiveRecord::Base 
    has_many :teams 
    has_many :teams, :through => :members 
end 

class Member < ActiveRecord::Base 
    belongs_to :team 
    belongs_to :person 
    # has a "position" which is a string 
end 

這種做法引起了我兩個問題:

  1. 團隊的belongs_to的:head_coach和:assistant_coach不起作用。也許它應該是一個has_one,但是我不確定將belongs_to放在Person中是否有意義(我想要Team中的FK到Person)。下面的例子表明,我怎麼把它建立不合拍用ActiveRecord:

    irb(main):006:0> t = Team.find(1) 
    => #<Team id: 1, name: "Champs", created_at: "2011-07-18 01:50:56", updated_at: "2011-07-19 01:47:26", head_coach: nil> 
    irb(main):007:0> t.head_coach 
    => nil 
    irb(main):008:0> t.head_coach = Person.find(1) 
    => #<Person id: 1, name: "Chris", created_at: "2011-07-18 01:52:34", updated_at: "2011-07-18 01:52:34"> 
    irb(main):009:0> t.save 
    => true 
    irb(main):010:0> t.head_coach 
    => #<Person id: 1, name: "Chris", created_at: "2011-07-18 01:52:34", updated_at: "2011-07-18 01:52:34"> 
    irb(main):011:0> Team.find(1).head_coach 
    => nil 
    
  2. 的的has_many:通過似乎工作,但我還沒有找到一個很好的方式列出每個人的位置在一個團隊內。這是在一個視圖中我目前的嘗試:

    <% @team.people.each do |person| %> 
        <%= person.name +" "+ @team.members.find_by_person_id(person).position %> 
    

是否有代表這些關係的整體更好的方法?

感謝您的幫助!

克里斯

回答

0

我最終使用下面的方法使用明確的foreign_key工作正常。

class Team < ActiveRecord::Base 
    has_many :members 
    has_many :people, :through => :members 
    belongs_to :head_coach, :class => 'Person', :foreign_key head_coach_id 
    belongs_to :assistant_coach, :class => 'Person', :foreign_key assistant_coach_id 
end 

class Person < ActiveRecord::Base 
    has_many :teams, :through => :members 

end 

class Member < ActiveRecord::Base 
    belongs_to :team 
    belongs_to :person 
    # has a "position" which is a string 
end 

到目前爲止唯一的缺點是我還沒有能夠獲得外鍵在控制器中自動加載。我需要添加以下代碼以便保存關聯:

# POST /teams 
def create 
    @team = Team.new 
    @team.head_coach = Person.find(params[:head_coach]) 
    @team.assistant_coach = Person.find(params[:assistant_coach]) 

    .... 
0

你可以爲head_coach和assistant_coach一個布爾字段在你的會員表,並使用驗證獨特的規則與範圍。

EG 加入會員表

is_head_coach:boolean 
is_assistant_coach:boolean 

現在,在您的會員模式有

validates_uniqueness_of :is_head_coach, :scope => [:team_id, :person_id] 
validates_uniqueness_of :is_assistant_coach, :scope => [:team_id, :person_id] 

然後你可以使用一些命名範圍在人模型或團隊模式找到head_coach。

至於列出所有的位置不能使用:

@team.members.each do |member| 
    "#{member.person.name} #{member.position}" 

如果你想他們在一個特定的方式進行排序,也許你可以添加一個字段名爲SORT_ORDER:整數成員表和排序那。

更新:

我同意你的觀點,上面這個解決方案是不可擴展的。怎麼樣,如果你使用的位置字段在您的會員模型,並創建一個又名「命名範圍」範圍爲它類似如下:

scope :head_coach, lambda { where('position = 'head coach') } 

然後,你可以使用類似:

team.members.head_coach 

你可以更進一步與此範圍

scope :get_position, lambda{|pos| where('position = ?', pos)} 

,並使用

team.members.get_position('head_coach') 

你可以編寫一個自定義的驗證方法來檢查你是否在每個團隊的head_coach上等。

+0

感謝您的建議。關於第一部分,我打算擴大規模,以便它還會有更多(「n」)角色,比如投球教練,擊球教練,基地教練,經理等......我喜歡範圍建議,但我想知道如果我結束了許多不同的角色將如何擴展? – krsyoung

相關問題