2012-06-25 2 views
1

Вот что у меня есть:Эффективное моделирование отношений 2: n в Rails

У меня есть модель Матч и модель Команда. В матче есть home_team и away_team. На самом деле это соотношение 2: n.

class Team < ActiveRecord::Base 
has_many :home_matches, :class_name => 'Match', :foreign_key => 'home_team_id' 
has_many :away_matches, :class_name => 'Match', :foreign_key => 'away_team_id' 

public 
def matches 
    return home_matches + away_matches 
end 
end 

и

class Match < ActiveRecord::Base 
attr_accessible :away_team_id, :home_team_id 
belongs_to :home_team, :class_name => 'Team', :foreign_key => 'home_team_id' 
belongs_to :away_team, :class_name => 'Team', :foreign_key => 'away_team_id' 

конец

Эффективно теперь я могу назвать Team.find (2) .matches и получить все прочь и домашние матчи. Но , что мне не нравится то, что он нуждается в двух SQL запросов вместо одного:

SELECT `matches`.* FROM `matches` WHERE `matches`.`home_team_id` = 2 
SELECT `matches`.* FROM `matches` WHERE `matches`.`away_team_id` = 2 

Как я могу получить Rails использовать этот запрос?

SELECT `matches`.* FROM `matches` WHERE `matches`.`home_team_id` = 2 OR `matches`.`away_team_id` = 2 

Другой способ вызывает ту же головную боль; Если я определяю метод team, который объединяет home_team и away_team Я запрашиваю БД два раза, когда требуется только один запрос.

ответ

3
def matches 
    Match.where("home_team_id = ? OR away_team_id = ?", id) 
end 

Кроме того, вам не нужны эти внешние ключи в модели Match. Эти атрибуты содержатся в самой модели Match и поэтому не являются иностранными.

+0

О, вы правы. Внешними ключами были ошибки копирования/вставки ... Во всяком случае, Я пытался быть чистым и использовал встроенные отношения ActiveRecord для моделирования этого поведения. Но ваше решение работает, по крайней мере, с точки зрения единого SQL-запроса (самый важный момент) ... Я надеялся на опции, которые я могу включить в предложения belongs_to и has_many. Ни за что? – EasierSaidThanDone