rails中的多级关联

我正在创建一个应用程序来跟踪整个赛季的足球队。 但我坚持数据库的设计。 一个夹具有一个主队和一个客队。 我创建了一个夹具模型,它有两个外键 – home_team和away_team,但我不能让关联正常工作。 有任何想法吗? 每个夹具都属于一个联盟。

简单的答案是:

class Fixture < ActiveRecord::Base belongs_to :home_team, :class_name => "Team", :foreign_key => :home_team belongs_to :away_team, :class_name => "Team", :foreign_key => :away_team end class Team < ActiveRecord::Base has_many :fixtures end 

但是,如果你因为Team.fixtures不起作用,那就不好了。

 class Team < ActiveRecord::Base has_many :home_fixtures, :class_name => "Fixtures", :foreign_key => :home_team has_many :away_fixtures, :class_name => "Fixtures", :foreign_key => :away_team end 

会给你两个collections品......但聚合它们必须在ruby中发生,这将是icky。

 class Team < ActiveRecord::Base def fixtures(*args) home_fixtures.all(*args) + away_fixtures.all(*args) end end 

这也有它的问题,排序和限制将全部投入(嘿,双关语,谁知道?)。

 class Team < ActiveRecord::Base has_many :fixtures, :finder_sql => 'SELECT * FROM fixtures where (home_team = #{id} or away_team = #{id})' has_many :home_fixtures, :class_name => "Fixtures", :foreign_key => :home_team has_many :away_fixtures, :class_name => "Fixtures", :foreign_key => :away_team end 

这很难看,但可能会奏效。 finder_sql似乎做了所需的事情。

另一种选择是使用named_scope:

 class Fixture < ActiveRecord::Base named_scope :for_team_id, lambda{|team_id| {:conditions => ['(home_team = ? or away_team = ?)', team_id, team_id]} } belongs_to :home_team, :class_name => "Team", :foreign_key => :home_team belongs_to :away_team, :class_name => "Team", :foreign_key => :away_team end class Team < ActiveRecord::Base def fixtures Fixtures.for_team_id(id) end end 

最后一个解决方案是我坚持使用的解决方案,因为它是一个范围,它的行为很像一个只读关联,并防止:finder_sql可能会发生更多的怪癖(我的意思是真的吗?它是如何知道如何合并更多的条件?它有时会做一个子查询,一个子查询?这里不需要吗?)。

希望这可以帮助。

假设你有一个Team模型和一个Something Model,后者将有home_team_idaway_team_id

 class Something < ActiveRecord::Base belongs_to :home_team, :class_name => 'Team' belongs_to :away_team, :class_name => 'Team' 

你会将它们称为something.away_teamsomething.home_team