rails中的多级关联

时间:2009-09-01 12:27:04

标签: ruby-on-rails table-relationships

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

2 个答案:

答案 0 :(得分:7)

简单的答案是:

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

会给你两个收藏品......但聚合它们必须在红宝石中发生,这将是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诡计(我的意思是真的吗?)它是如何知道如何合并更多条件的呢?它有时会产生一个子查询,一个子查询?这里不需要吗?)。

希望这有帮助。

答案 1 :(得分:0)

假设您拥有Team模型和Something模型,后者将拥有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