ActiveRecord выбрать через несколько объединений - PullRequest
1 голос
/ 02 апреля 2012

Я работаю над веб-сервисом на основе Rails, который предоставляет данные о расписаниях различных спортивных команд.У меня есть модели, которые включали следующее:

  • Каждая запись Игры имеет команду "дома" и "выезда", каждая из которых ссылается на запись команды
  • Каждая запись команды принадлежитЗапись дивизии

Я смоделировал игру следующим образом:

class Game < ActiveRecord::Base

  # Miscellaneous validations here

  belongs_to :home_team, :class_name => Team
  belongs_to :away_team, :class_name => Team

  # Other stuff follows

end

Вот модель для команды:

class Team < ActiveRecord::Base

  # Miscellaneous validations here

  belongs_to :division

  # Other stuff follows

end

А вот модель дляПодразделение:

class Division < ActiveRecord::Base

  # Miscellaneous validations here

  has_many :teams, :dependent => :destroy

  # Other stuff follows

end

Я пытаюсь выполнить запрос на возврат всех игр, в которых команда хозяев и команда выезжают из определенного подразделения.В псевдокоде я хочу что-то вроде:

SELECT games.* FROM games WHERE 
    "The division ID of the home team" = '1' AND
    "The division ID of the away team" = '1' 

Я пробовал различные воплощения, используя метод соединения, ни один из которых не работал для меня.Самое близкое, что я получил, это:

games = Game.joins(:home_team, :away_team).where(
    :home_team => {:division_id => params[:division_id]}, 
    :away_team => {:division_id => params[:division_id]})

, но это дает мне ошибку:

  SQLite3::SQLException: no such column: home_team.division_id: SELECT "games".* FROM "games" INNER JOIN "teams" ON "teams"."id" = "games"."home_team_id" INNER JOIN "teams" "away_teams_games" ON "away_teams_games"."id" = "games"."away_team_id" WHERE "home_team"."division_id" = '1' AND "away_team"."division_id" = '1'

Ясно, что мой синтаксис для определенных home_team и away_team не работает, потому что он не работаетсопоставляя их с действительным именем таблицы «команд».Но любой другой вариант объединения, которое я придумаю, кажется, еще больше помогает мне достичь того, чего я хочу.

Буду признателен за любую помощь, которую вы можете предоставить, или ссылки на документацию, которая покажет мне, как это сделать.вещь.

Ответы [ 2 ]

3 голосов
/ 03 апреля 2012

Хотя ответ, предоставленный @tsherif, помог мне, я также хотел поделиться альтернативным подходом, который я нашел, основываясь на информации, которую я нашел в другом месте.

Оказывается, ActiveRecord реализует свои собственные правила для псевдонимов таблиц, когда вы ссылаетесь на одну и ту же таблицу дважды в объединениях. Этот псевдоним описан в разделе «Псевдоним таблицы» этой ссылки . На основании этой информации я смог определить, что вторая ассоциация, указанная в моем объединении (:away_team), получила псевдоним away_teams_games. Имея в виду псевдоним таблицы, я смог заставить все работать, используя это:

  games = Game.joins(:home_team, :away_team).where(
      :teams => {:division_id => params[:division_id]},
      :away_teams_games => {:division_id => params[:division_id]})

Хотя это было не совсем очевидно для меня, когда я впервые посмотрел на него, теперь, когда я вижу, что происходит, в этом есть какой-то смысл.

1 голос
/ 02 апреля 2012

Я думаю, что вы могли бы попробовать что-то вроде этого:

Game.where(["(SELECT COUNT(DISTINCT teams.id) FROM teams WHERE teams.division_id = ? AND (teams.id=games.home_team_id OR teams.id=games.away_team_id)) = 2", params[:division_id]])

У вас есть вложенный запрос, который немного раздражает, но он позволяет вам избежать необходимости дважды объединяться с таблицей команд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...