I've got the following structure set up in ActiveRecord in 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
Somewhere in my controller I want to find other videos from a video based on a certain tag, wich is quite easy using the find_related_tags method. But I need to restrict the related videos to the current domain which is present through a helper method called current_domain
, so I came up with the following AR query:
@video = Video.find(params[:id])
@video.find_related_tags.joins(:domains).with_state(:converted).where('domains.id = ?', current_domain.id)
This AR query produces the following MySQL query:
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
It seems fine to me, but it produces a MySQL error:
Mysql2::Error: Unknown column 'videos.id' in 'on clause'
And that I don't get! Why is videos.id an unkown column in
INNER JOIN `domains_videos` ON `domains_videos`.`video_id` = `videos`.`id`
All join tables are properly set up. Everything works. If I remove the .joins(:domains)
part it works... I'm sure it's something simple I'm just not seeing :)
It seems that the MySQL query is valid, but the videos.id column is unknown cause videos is not in the join set but only used in the FROM clause. So I ended up with the solution to do the following:
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}
")
Since everything is really joined now, the statement now is valid for MySQL.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.