perf: batch preload hashtags/tags/category/user names in get_videos to avoid N+1 queries

This commit is contained in:
rulingcom 2026-07-21 17:38:29 +08:00
parent 1b1157f232
commit 13738e6d87
2 changed files with 32 additions and 13 deletions

View File

@ -240,18 +240,33 @@ class VideoProsController < ApplicationController
end
private
def get_videos(video_images, show_url, custom_data_field={})
@autoplay_video = custom_data_field[:autoplay_video] rescue "0"
@hide_video_tools = custom_data_field[:hide_video_tools] == "1" rescue false
videos = []
video_images.each_with_index do |video_image,i|
def get_videos(video_images, show_url, custom_data_field={})
@autoplay_video = custom_data_field[:autoplay_video] rescue "0"
@hide_video_tools = custom_data_field[:hide_video_tools] == "1" rescue false
video_image_ids = video_images.map(&:id)
hashtaggings_by_video = Hashtagging.where(:hashtaggable_id.in => video_image_ids, :hashtaggable_type => "VideoImage").group_by(&:hashtaggable_id)
all_hashtag_ids = hashtaggings_by_video.values.flatten.map(&:hashtag_id).compact.uniq
hashtags_by_id = Hashtag.where(:id.in => all_hashtag_ids).to_a.index_by(&:id)
taggings_by_video = Tagging.where(:taggable_id.in => video_image_ids, :taggable_type => "VideoImage").group_by(&:taggable_id)
all_tag_ids = taggings_by_video.values.flatten.map(&:tag_id).compact.uniq
tags_by_id = Tag.where(:id.in => all_tag_ids).to_a.index_by(&:id)
all_category_ids = video_images.map(&:category_id).compact.uniq
categories_by_id = Category.where(:id.in => all_category_ids).to_a.index_by(&:id)
id_name_mapping = User.where(:id.in=>video_images.map(&:update_user_id).compact.uniq).pluck(:id, "member_name.#{I18n.locale}").map{|k,v| [k.to_s, (v ? v.values.last : nil)]}.to_h
videos = []
video_images.each_with_index do |video_image,i|
if video_image.language_enabled.include?(I18n.locale.to_s)
snapshot_url = video_image.get_snapshot_url
next if snapshot_url.nil?
video_post_agency = video_image.post_agency(@video_pro_setting)
video_post_agency = video_image.post_agency(@video_pro_setting, id_name_mapping)
video_postdate = video_image.postdate.to_s
video_category = video_image.category_title
video_tags = video_image.tags
video_category = video_image.category_title(categories_by_id[video_image.category_id])
video_tags = video_image.tags((taggings_by_video[video_image.id] || []).map{|tg| tags_by_id[tg.tag_id]}.compact)
video_tags = (video_tags.count > 0 ? video_tags.collect{|tag| {"video_tag" => tag.name}} : [{"video_tag" => video_category}])
statuses = video_image.statuses_with_classname
video_desc = video_image.desc

View File

@ -89,9 +89,11 @@ class VideoImage
def inc_count
self.class.where(:id=>self.id).update_all({"$inc"=>{"view_count"=>1}})
end
def category_title
self.category.title rescue ""
def category_title(preloaded_category=nil)
self.category(preloaded_category).title rescue ""
end
def post_agencies_translations
if defined?(OrbitHelper::SharedHash) && OrbitHelper::SharedHash
OrbitHelper::SharedHash['video_pro'][:post_agencies_translations] rescue VideoProSetting.first.post_agencies_translations
@ -102,7 +104,8 @@ class VideoImage
def get_override_post_agency
self.post_agencies_translations[I18n.locale.to_s][self.override_post_agency] rescue ""
end
def post_agency(video_pro_setting=nil)
def post_agency(video_pro_setting=nil, id_name_mapping=nil)
if self.use_override_post_agency
self.get_override_post_agency
else
@ -112,16 +115,17 @@ class VideoImage
if video_pro_setting && video_pro_setting.enable_name_mapping
tmp = video_pro_setting.user_mapping[self.update_user_id] rescue nil
if tmp.blank?
user_name = User.where(:id=>self.update_user_id).pluck(:member_name).first[I18n.locale.to_s] rescue nil
user_name = id_name_mapping ? id_name_mapping[self.update_user_id] : (User.where(:id=>self.update_user_id).pluck(:member_name).first[I18n.locale.to_s] rescue nil)
else
user_name = tmp
end
else
user_name = User.where(:id=>self.update_user_id).pluck(:member_name).first[I18n.locale.to_s] rescue nil
user_name = id_name_mapping ? id_name_mapping[self.update_user_id] : (User.where(:id=>self.update_user_id).pluck(:member_name).first[I18n.locale.to_s] rescue nil)
end
user_name
end
end
def generate_video_snapshot
if self.video_file?
self.default_video_snapshot = true