У меня есть 3 модели
class Battle < ActiveRecord::Base
has_many :battle_videos
has_many :videos, :through => :battle_videos
...
end
class BattleVideo < ActiveRecord::Base
belongs_to :battle
belongs_to :video
validates :code, :presence => true
end
class Video < ActiveRecord::Base
belongs_to :user, :foreign_key => :user_id, :class_name => "User"
...
end
У BattleVideo есть атрибут «код» (left_side || right_side), который определяет СТОРОНУ БИТВЫ (всегда есть 2 стороны в битвах, потому что всегда играет - 1 против 1, команда против команды и т. д.)
Я бы хотел указать ассоциацию (left_side_video, right_side_video) в видео модели, которая получает видео для выбранной стороны.
Теперь, чтобы получить видео для SIDE 1 (слева) - используйте этот код
Battle.first.battle_videos.where("battle_videos.code = 'left_side'").first.video
Я хочу, чтобы мои боевые видео были такими
Battle.first.left_side_video
Я думаю, модель битвы должна выглядеть так, но она не работает (работает тольколевая сторона)
class Battle < ActiveRecord::Base
has_many :battle_videos
has_many :videos, :through => :battle_videos
has_many :left_side_video, :through => :battle_videos, :source => :video, :conditions => ["battle_videos.code = 'left_side'"]
has_many :right_side_video, :through => :battle_videos, :source => :video, :conditions => ["battle_videos.code = 'right_side'"]
end
ОБНОВЛЕНИЕ: Работает, но не по желанию.Проблема была в includes
цепочке.модель Battle
имеет область действия :all_inclusive
, которая загружает все ассоциации
scope :all_inclusive, includes(:battle_category).includes(:bets).includes(:votes).includes(:left_side_video).includes(:right_side_video)
Генерируемый SQL:
Battle Load (0.6ms) SELECT `battles`.* FROM `battles` WHERE (battles.status = 1 AND valid_from < '2012-01-31 13:31:50' AND battles.valid_to > '2012-01-31 13:31:50') ORDER BY battles.id DESC
BattleCategory Load (0.1ms) SELECT `battle_categories`.* FROM `battle_categories` WHERE `battle_categories`.`id` IN (1)
Bet Load (0.1ms) SELECT `bets`.* FROM `bets` WHERE `bets`.`parent_type` = 'Battle' AND `bets`.`parent_id` IN (1, 2)
Vote Load (0.2ms) SELECT `votes`.* FROM `votes` WHERE `votes`.`parent_type` = 'Battle' AND `votes`.`parent_id` IN (1, 2)
BattleVideo Load (0.1ms) SELECT `battle_videos`.* FROM `battle_videos` WHERE `battle_videos`.`battle_id` IN (1, 2) AND (battle_videos.code = 'user_1')
Video Load (0.1ms) SELECT `videos`.* FROM `videos` WHERE `videos`.`id` IN (1, 3)
УВЕДОМЛЕНИЕ, ЧТО ВИДЕО 2 И 4 (ДЛЯ ПРАВОЙ СТОРОНЫ) -не загружается.Я могу получить доступ только к 1,3 видео
Идентификатор видео, идентификатор боя (сторона)
[1, 1 (lft)]
[2, 1 (rgt))]
[3, 2 (lft)]
[4, 2 (rgt)]
Когда я удаляю .includes(:right_side_video)
из :all_inclusive
цепи, я получил этоsql:
Battle Load (0.6ms) SELECT `battles`.* FROM `battles` WHERE (battles.status = 1 AND valid_from < '2012-01-31 13:39:26' AND battles.valid_to > '2012-01-31 13:39:26') ORDER BY battles.id DESC
BattleCategory Load (0.1ms) SELECT `battle_categories`.* FROM `battle_categories` WHERE `battle_categories`.`id` IN (1)
Bet Load (0.1ms) SELECT `bets`.* FROM `bets` WHERE `bets`.`parent_type` = 'Battle' AND `bets`.`parent_id` IN (1,2)
Vote Load (0.2ms) SELECT `votes`.* FROM `votes` WHERE `votes`.`parent_type` = 'Battle' AND `votes`.`parent_id` IN (1,2)
BattleVideo Load (0.3ms) SELECT `battle_videos`.* FROM `battle_videos` WHERE `battle_videos`.`battle_id` IN (1,2) AND (battle_videos.code = 'left_side')
Video Load (0.1ms) SELECT `videos`.* FROM `videos` WHERE `videos`.`id` IN (1, 3)
Video Load (0.2ms) SELECT `videos`.* FROM `videos` INNER JOIN `battle_videos` ON `videos`.`id` = `battle_videos`.`video_id` WHERE `battle_videos`.`battle_id` = 1 AND (battle_videos.code = 'right_side') LIMIT 1
Video Load (0.1ms) SELECT `videos`.* FROM `videos` INNER JOIN `battle_videos` ON `videos`.`id` = `battle_videos`.`video_id` WHERE `battle_videos`.`battle_id` = 2 AND (battle_videos.code = 'right_side') LIMIT 1
Теперь это работает нормально.Но на уровне SQL - это не так идеально, как я хочу.Вы можете видеть, что видео 1, 3 загружаются правильно
Video Load (0.1ms) SELECT `videos`.* FROM `videos` WHERE `videos`.`id` IN (1, 3)
Но видео 2, 4 загружается отдельными sqls:
Video Load (0.2ms) SELECT `videos`.* FROM `videos` INNER JOIN `battle_videos` ON `videos`.`id` = `battle_videos`.`video_id` WHERE `battle_videos`.`battle_id` = 1 AND (battle_videos.code = 'right_side') LIMIT 1
Video Load (0.1ms) SELECT `videos`.* FROM `videos` INNER JOIN `battle_videos` ON `videos`.`id` = `battle_videos`.`video_id` WHERE `battle_videos`.`battle_id` = 2 AND (battle_videos.code = 'right_side') LIMIT 1
Что я хочу? FINAL SQL, созданный RUBY
Video Load (0.1ms) SELECT `videos`.* FROM `videos` WHERE `videos`.`id` IN (1, 2, 3, 4)