From 00b9fc3d8809ac876967b698e4d1e60eb1cb5bd0 Mon Sep 17 00:00:00 2001 From: Victor Costa Date: Tue, 5 Aug 2014 14:34:56 -0300 Subject: [PATCH] Added includes in models to prevent n+1 queries --- app/controllers/my_profile/cms_controller.rb | 2 +- app/controllers/public/content_viewer_controller.rb | 2 +- app/models/article.rb | 10 +++++----- app/models/category.rb | 2 +- app/models/comment.rb | 2 +- app/models/person.rb | 2 +- app/models/profile.rb | 2 +- lib/acts_as_having_posts.rb | 2 +- lib/spammable.rb | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index b641e84..ed58294 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -59,7 +59,7 @@ class CmsController < MyProfileController conditions = ['type != ?', 'RssFeed'] end - @articles = @article.children.reorder("case when type = 'Folder' then 0 when type ='Blog' then 1 else 2 end, updated_at DESC, name").paginate( + @articles = @article.children.includes(:parent).reorder("case when type = 'Folder' then 0 when type ='Blog' then 1 else 2 end, updated_at DESC, name").paginate( :conditions => conditions, :per_page => per_page, :page => params[:npage] diff --git a/app/controllers/public/content_viewer_controller.rb b/app/controllers/public/content_viewer_controller.rb index ea5925a..c866537 100644 --- a/app/controllers/public/content_viewer_controller.rb +++ b/app/controllers/public/content_viewer_controller.rb @@ -221,7 +221,7 @@ class ContentViewerController < ApplicationController # relation. posts = posts.native_translations if blog_with_translation?(@page) - @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))).to_a + @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))).includes(:author).to_a if blog_with_translation?(@page) @posts.replace @posts.map{ |p| p.get_translation_to(FastGettext.locale) }.compact diff --git a/app/models/article.rb b/app/models/article.rb index 6023bfb..27b7cf0 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -58,10 +58,10 @@ class Article < ActiveRecord::Base belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id' - has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'comments.created_at asc', :include => [:author, :children] has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ] - has_many :categories, :through => :article_categorizations + has_many :categories, :through => :article_categorizations, :include => [:environment] has_many :article_categorizations_including_virtual, :class_name => 'ArticleCategorization' has_many :categories_including_virtual, :through => :article_categorizations_including_virtual, :source => :category @@ -236,7 +236,7 @@ class Article < ActiveRecord::Base # retrieves all articles belonging to the given +profile+ that are not # sub-articles of any other article. scope :top_level_for, lambda { |profile| - {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ]} + {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ], :include => [:profile]} } scope :public, @@ -460,7 +460,7 @@ class Article < ActiveRecord::Base end scope :published, :conditions => ['articles.published = ?', true] - scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }} + scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types], :include => [:parent] }} scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}} scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ] scope :images, :conditions => { :is_image => true } @@ -469,7 +469,7 @@ class Article < ActiveRecord::Base scope :more_popular, :order => 'hits DESC' scope :more_comments, :order => "comments_count DESC" - scope :more_recent, :order => "created_at DESC" + scope :more_recent, :order => "articles.created_at DESC" def self.display_filter(user, profile) return {:conditions => ['articles.published = ?', true]} if !user diff --git a/app/models/category.rb b/app/models/category.rb index 2c4aa67..ab214b9 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -16,7 +16,7 @@ class Category < ActiveRecord::Base # Finds all top level categories for a given environment. scope :top_level_for, lambda { |environment| - {:conditions => ['parent_id is null and environment_id = ?', environment.id ]} + {:conditions => ['parent_id is null and environment_id = ?', environment.id ], :include => [:children]} } scope :on_level, lambda { |parent| {:conditions => {:parent_id => parent}} } diff --git a/app/models/comment.rb b/app/models/comment.rb index 99941d8..5310a4f 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -18,7 +18,7 @@ class Comment < ActiveRecord::Base has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' - scope :without_reply, :conditions => ['reply_of_id IS NULL'] + scope :without_reply, :conditions => ['comments.reply_of_id IS NULL'] # unauthenticated authors: validates_presence_of :name, :if => (lambda { |record| !record.email.blank? }) diff --git a/app/models/person.rb b/app/models/person.rb index df39448..53ec490 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -434,7 +434,7 @@ class Person < Profile end def already_reported?(profile) - abuse_reports.any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? } + abuse_reports.includes({:abuse_complaint => :reported}).any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? } end def register_report(abuse_report, profile) diff --git a/app/models/profile.rb b/app/models/profile.rb index 0879322..364b3be 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -190,7 +190,7 @@ class Profile < ActiveRecord::Base belongs_to :preferred_domain, :class_name => 'Domain', :foreign_key => 'preferred_domain_id' belongs_to :environment - has_many :articles, :dependent => :destroy + has_many :articles, :dependent => :destroy, :include => [:profile] belongs_to :home_page, :class_name => Article.name, :foreign_key => 'home_page_id' has_many :files, :class_name => 'UploadedFile' diff --git a/lib/acts_as_having_posts.rb b/lib/acts_as_having_posts.rb index 68ef4a7..9c9c020 100644 --- a/lib/acts_as_having_posts.rb +++ b/lib/acts_as_having_posts.rb @@ -2,7 +2,7 @@ module ActsAsHavingPosts module ClassMethods def acts_as_having_posts(options = {}) - has_many :posts, { :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'articles.type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC' }.merge(options) + has_many :posts, { :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'articles.type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC', :include => [:parent, :profile] }.merge(options) attr_accessor :feed_attrs diff --git a/lib/spammable.rb b/lib/spammable.rb index eff1206..2605f9d 100644 --- a/lib/spammable.rb +++ b/lib/spammable.rb @@ -12,8 +12,8 @@ module Spammable def self.extended (base) if base.respond_to?(:scope) base.class_eval do - scope :without_spam, :conditions => ['spam IS NULL OR spam = ?', false] - scope :spam, :conditions => ['spam = ?', true] + scope :without_spam, :conditions => ["#{base.table_name}.spam IS NULL OR #{base.table_name}.spam = ?", false] + scope :spam, :conditions => ["#{base.table_name}.spam = ?", true] end end end -- libgit2 0.21.2