【发布时间】:2010-11-24 15:14:49
【问题描述】:
我正在创建一个应用程序来跟踪整个赛季的足球队。但我被困在数据库的设计上。一个固定装置有一支主队和一支客队。我创建了一个夹具模型,它有两个外键——home_team 和 away_team,但我无法让关联正常工作。有任何想法吗?每个赛程都属于一个联赛。
【问题讨论】:
标签: ruby-on-rails table-relationships
我正在创建一个应用程序来跟踪整个赛季的足球队。但我被困在数据库的设计上。一个固定装置有一支主队和一支客队。我创建了一个夹具模型,它有两个外键——home_team 和 away_team,但我无法让关联正常工作。有任何想法吗?每个赛程都属于一个联赛。
【问题讨论】:
标签: ruby-on-rails table-relationships
简单的答案是:
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
会给你两个集合...但是聚合它们必须在 ruby 中进行,这会很恶心。
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 模型,后者将有home_team_id 和away_team_id。
class Something < ActiveRecord::Base
belongs_to :home_team, :class_name => 'Team'
belongs_to :away_team, :class_name => 'Team'
您将它们称为something.away_team 和something.home_team。
【讨论】: