Rails: внутреннее соединение с find_related_tagscts-as-taggable-on выдает ошибку mysql - PullRequest
0 голосов
/ 15 февраля 2012

У меня установлена ​​следующая структура в ActiveRecord в Rails 3

class Domain < AR
  has_and_belongs_to_many :videos
end

class Video < AR
  has_and_belongs_to_many :domains
  acts_as_taggable_on :tags
  scope :with_state, lambda { |s| where('state = ?', s)  }
end

Где-то в моем контроллере я хочу найти другие видео из видео, основанного на определенном теге, который довольно легко использовать с помощью метода find_related_tags. Но мне нужно ограничить связанные видео текущим доменом, который присутствует через вспомогательный метод с именем current_domain, поэтому я пришел к следующему AR-запросу:

@video = Video.find(params[:id])
@video.find_related_tags.joins(:domains).with_state(:converted).where('domains.id = ?', current_domain.id)

Этот AR-запрос создает следующий запрос MySQL:

SELECT videos.*, COUNT(tags.id) AS count FROM videos, tags, taggings
INNER JOIN `domains_videos` ON `domains_videos`.`video_id` = `videos`.`id`
INNER JOIN `domains` ON `domains`.`id` = `domains_videos`.`domain_id`
WHERE (videos.id != 5 AND videos.id = taggings.taggable_id 
  AND taggings.taggable_type = 'Video'
  AND taggings.tag_id = tags.id
  AND tags.name IN ('not'))
  AND (state = 'converted')
  AND (domains.id = 4)
GROUP BY videos.id
ORDER BY count DESC

Мне кажется, что это нормально, но выдает ошибку MySQL:

Mysql2::Error: Unknown column 'videos.id' in 'on clause'

И это я не понимаю! Почему videos.id - неизвестный столбец в

INNER JOIN `domains_videos` ON `domains_videos`.`video_id` = `videos`.`id`

Все соединительные таблицы настроены правильно. Все работает. Если я удаляю часть .joins(:domains), она работает ... Я уверен, что это что-то простое, я просто не вижу :)

1 Ответ

0 голосов
/ 12 марта 2012

Кажется, что запрос MySQL действителен, но столбец videos.id неизвестен, потому что видео не входит в набор соединений, а используется только в предложении FROM. В итоге я решил сделать следующее:

Video.find_by_sql("
  SELECT videos.*, COUNT(tags.id) AS count
  FROM videos
  INNER JOIN domains_videos ON domains_videos.video_id = videos.id
  INNER JOIN domains ON domains.id = domains_videos.domain_id
  INNER JOIN taggings ON videos.id = taggings.taggable_id AND taggings.taggable_type = '#{self.class.to_s}'
  INNER JOIN tags ON taggings.tag_id = tags.id
  WHERE tags.name IN (#{joined_tags})
  AND videos.state = 'converted'
  AND domains.id = #{domain.id}
  AND videos.id != #{id}
  GROUP BY videos.id
  ORDER BY count DESC
  LIMIT #{limit}
")

Поскольку теперь все действительно объединено, оператор теперь действителен для MySQL.

...