From 13738e6d87edd3592968d5a95f2379b8cdbff6f7 Mon Sep 17 00:00:00 2001 From: rulingcom Date: Tue, 21 Jul 2026 17:38:29 +0800 Subject: [PATCH] perf: batch preload hashtags/tags/category/user names in get_videos to avoid N+1 queries --- app/controllers/video_pros_controller.rb | 31 ++++++++++++++++++------ app/models/video_image.rb | 14 +++++++---- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/app/controllers/video_pros_controller.rb b/app/controllers/video_pros_controller.rb index 274c064..cca7396 100644 --- a/app/controllers/video_pros_controller.rb +++ b/app/controllers/video_pros_controller.rb @@ -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 diff --git a/app/models/video_image.rb b/app/models/video_image.rb index 3889f9e..fbe11c7 100644 --- a/app/models/video_image.rb +++ b/app/models/video_image.rb @@ -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