Простой ответ:
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
, которая может произойти дальше (я имею в виду на самом деле? он знает, как объединить больше условий? Иногда он делает подзапрос, подзапрос? Это просто не нужно здесь?).
Надеюсь, это поможет.