Commit d482447c1824b0323f1fb0ac0f67e66785dc8e32

Authored by Rodrigo Souto
1 parent f9296a1f

[performance] Reducing overall database queries

app/controllers/public/profile_controller.rb
@@ -49,36 +49,36 @@ class ProfileController < PublicController @@ -49,36 +49,36 @@ class ProfileController < PublicController
49 49
50 def communities 50 def communities
51 if is_cache_expired?(profile.communities_cache_key(params)) 51 if is_cache_expired?(profile.communities_cache_key(params))
52 - @communities = profile.communities.paginate(:per_page => per_page, :page => params[:npage]) 52 + @communities = profile.communities.includes(relations_to_include).paginate(:per_page => per_page, :page => params[:npage])
53 end 53 end
54 end 54 end
55 55
56 def enterprises 56 def enterprises
57 - @enterprises = profile.enterprises 57 + @enterprises = profile.enterprises.includes(relations_to_include)
58 end 58 end
59 59
60 def friends 60 def friends
61 if is_cache_expired?(profile.friends_cache_key(params)) 61 if is_cache_expired?(profile.friends_cache_key(params))
62 - @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage]) 62 + @friends = profile.friends.includes(relations_to_include).paginate(:per_page => per_page, :page => params[:npage])
63 end 63 end
64 end 64 end
65 65
66 def members 66 def members
67 if is_cache_expired?(profile.members_cache_key(params)) 67 if is_cache_expired?(profile.members_cache_key(params))
68 - @members = profile.members.paginate(:per_page => members_per_page, :page => params[:npage]) 68 + @members = profile.members.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
69 end 69 end
70 end 70 end
71 71
72 def fans 72 def fans
73 - @fans = profile.fans 73 + @fans = profile.fans.includes(relations_to_include)
74 end 74 end
75 75
76 def favorite_enterprises 76 def favorite_enterprises
77 - @favorite_enterprises = profile.favorite_enterprises 77 + @favorite_enterprises = profile.favorite_enterprises.includes(relations_to_include)
78 end 78 end
79 79
80 def sitemap 80 def sitemap
81 - @articles = profile.top_level_articles 81 + @articles = profile.top_level_articles.includes([:profile, :parent])
82 end 82 end
83 83
84 def join 84 def join
@@ -246,7 +246,7 @@ class ProfileController < PublicController @@ -246,7 +246,7 @@ class ProfileController < PublicController
246 246
247 def profile_info 247 def profile_info
248 begin 248 begin
249 - @block = profile.blocks.find(params[:block_id]) 249 + @block = profile.blocks.find(params[:block_id]).includes(:box)
250 rescue 250 rescue
251 render :text => _('Profile information could not be loaded') 251 render :text => _('Profile information could not be loaded')
252 end 252 end
@@ -359,4 +359,8 @@ class ProfileController < PublicController @@ -359,4 +359,8 @@ class ProfileController < PublicController
359 @can_edit_profile ||= user && user.has_permission?('edit_profile', profile) 359 @can_edit_profile ||= user && user.has_permission?('edit_profile', profile)
360 end 360 end
361 helper_method :can_edit_profile 361 helper_method :can_edit_profile
  362 +
  363 + def relations_to_include
  364 + [:image, :domains, :preferred_domain, :environment]
  365 + end
362 end 366 end
app/controllers/public/search_controller.rb
@@ -46,7 +46,7 @@ class SearchController < PublicController @@ -46,7 +46,7 @@ class SearchController < PublicController
46 if !@empty_query 46 if !@empty_query
47 full_text_search ['public:true'] 47 full_text_search ['public:true']
48 else 48 else
49 - @results[@asset] = @environment.people.visible.send(@filter).paginate(paginate_options) 49 + @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options)
50 end 50 end
51 end 51 end
52 52
@@ -76,7 +76,7 @@ class SearchController < PublicController @@ -76,7 +76,7 @@ class SearchController < PublicController
76 full_text_search ['public:true'] 76 full_text_search ['public:true']
77 else 77 else
78 @filter_title = _('Enterprises from network') 78 @filter_title = _('Enterprises from network')
79 - @results[@asset] = @environment.enterprises.visible.paginate(paginate_options) 79 + @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options)
80 end 80 end
81 end 81 end
82 82
@@ -84,7 +84,7 @@ class SearchController < PublicController @@ -84,7 +84,7 @@ class SearchController < PublicController
84 if !@empty_query 84 if !@empty_query
85 full_text_search ['public:true'] 85 full_text_search ['public:true']
86 else 86 else
87 - @results[@asset] = @environment.communities.visible.send(@filter).paginate(paginate_options) 87 + @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options)
88 end 88 end
89 end 89 end
90 90
@@ -310,4 +310,12 @@ class SearchController < PublicController @@ -310,4 +310,12 @@ class SearchController < PublicController
310 @all_facets = ret[:all_facets] 310 @all_facets = ret[:all_facets]
311 end 311 end
312 312
  313 + private
  314 +
  315 + def visible_profiles(klass, *extra_relations)
  316 + relations = [:image, :domains, :environment, :preferred_domain]
  317 + relations += extra_relations
  318 + @environment.send(klass.name.underscore.pluralize).visible.includes(relations)
  319 + end
  320 +
313 end 321 end
app/helpers/boxes_helper.rb
@@ -66,7 +66,7 @@ module BoxesHelper @@ -66,7 +66,7 @@ module BoxesHelper
66 66
67 def display_box_content(box, main_content) 67 def display_box_content(box, main_content)
68 context = { :article => @page, :request_path => request.path, :locale => locale } 68 context = { :article => @page, :request_path => request.path, :locale => locale }
69 - box_decorator.select_blocks(box.blocks, context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) 69 + box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box)
70 end 70 end
71 71
72 def select_blocks(arr, context) 72 def select_blocks(arr, context)
app/models/article.rb
@@ -179,37 +179,23 @@ class Article < ActiveRecord::Base @@ -179,37 +179,23 @@ class Article < ActiveRecord::Base
179 end 179 end
180 180
181 named_scope :more_popular, :order => 'hits DESC' 181 named_scope :more_popular, :order => 'hits DESC'
182 -  
183 - # retrieves the latest +limit+ articles, sorted from the most recent to the  
184 - # oldest.  
185 - #  
186 - # Only includes articles where advertise == true  
187 - def self.recent(limit = nil, extra_conditions = {})  
188 - # FIXME this method is a horrible hack  
189 - options = { :page => 1, :per_page => limit,  
190 - :conditions => [  
191 - "advertise = ? AND  
192 - published = ? AND  
193 - profiles.visible = ? AND  
194 - profiles.public_profile = ? AND  
195 - ((articles.type != ? and articles.type != ? and articles.type != ?) OR articles.type is NULL)", true, true, true, true, 'UploadedFile', 'RssFeed', 'Blog'  
196 - ],  
197 - :include => 'profile',  
198 - :order => 'articles.published_at desc, articles.id desc'  
199 - }  
200 - if ( scoped_methods && scoped_methods.last &&  
201 - scoped_methods.last[:find] &&  
202 - scoped_methods.last[:find][:joins] &&  
203 - scoped_methods.last[:find][:joins].index('profiles') )  
204 - options.delete(:include)  
205 - end  
206 - if extra_conditions == {}  
207 - self.paginate(options)  
208 - else  
209 - with_scope :find => {:conditions => extra_conditions} do  
210 - self.paginate(options)  
211 - end 182 + named_scope :relevant_as_recent, :conditions => ["(articles.type != 'UploadedFile' and articles.type != 'RssFeed' and articles.type != 'Blog') OR articles.type is NULL"]
  183 +
  184 + def self.recent(limit = nil, extra_conditions = {}, pagination = true)
  185 + result = scoped({:conditions => extra_conditions}).
  186 + public.
  187 + relevant_as_recent.
  188 + limit(limit).
  189 + order(['articles.published_at desc', 'articles.id desc'])
  190 +
  191 + if !( scoped_methods && scoped_methods.last &&
  192 + scoped_methods.last[:find] &&
  193 + scoped_methods.last[:find][:joins] &&
  194 + scoped_methods.last[:find][:joins].index('profiles') )
  195 + result.includes(:profile)
212 end 196 end
  197 +
  198 + pagination ? result.paginate({:page => 1, :per_page => limit}) : result
213 end 199 end
214 200
215 # produces the HTML code that is to be displayed as this article's contents. 201 # produces the HTML code that is to be displayed as this article's contents.
app/models/enterprise.rb
@@ -17,7 +17,7 @@ class Enterprise < Organization @@ -17,7 +17,7 @@ class Enterprise < Organization
17 after_save_reindex [:products], :with => :delayed_job 17 after_save_reindex [:products], :with => :delayed_job
18 extra_data_for_index :product_categories 18 extra_data_for_index :product_categories
19 def product_categories 19 def product_categories
20 - products.map{|p| p.category_full_name}.compact 20 + products.includes(:product_category).map{|p| p.category_full_name}.compact
21 end 21 end
22 22
23 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') 23 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code')
app/models/environment.rb
@@ -591,8 +591,8 @@ class Environment < ActiveRecord::Base @@ -591,8 +591,8 @@ class Environment < ActiveRecord::Base
591 end 591 end
592 592
593 has_many :articles, :through => :profiles 593 has_many :articles, :through => :profiles
594 - def recent_documents(limit = 10)  
595 - self.articles.recent(limit) 594 + def recent_documents(limit = 10, options = {}, pagination = true)
  595 + self.articles.recent(limit, options, pagination)
596 end 596 end
597 597
598 has_many :events, :through => :profiles, :source => :articles, :class_name => 'Event' 598 has_many :events, :through => :profiles, :source => :articles, :class_name => 'Event'
app/models/person.rb
@@ -251,7 +251,7 @@ class Person < Profile @@ -251,7 +251,7 @@ class Person < Profile
251 251
252 def is_admin?(environment = nil) 252 def is_admin?(environment = nil)
253 environment ||= self.environment 253 environment ||= self.environment
254 - role_assignments.select { |ra| ra.resource == environment }.map{|ra|ra.role.permissions}.any? do |ps| 254 + role_assignments.includes([:role, :resource]).select { |ra| ra.resource == environment }.map{|ra|ra.role.permissions}.any? do |ps|
255 ps.any? do |p| 255 ps.any? do |p|
256 ActiveRecord::Base::PERMISSIONS['Environment'].keys.include?(p) 256 ActiveRecord::Base::PERMISSIONS['Environment'].keys.include?(p)
257 end 257 end
app/models/profile.rb
@@ -398,8 +398,8 @@ class Profile < ActiveRecord::Base @@ -398,8 +398,8 @@ class Profile < ActiveRecord::Base
398 # 398 #
399 # +limit+ is the maximum number of documents to be returned. It defaults to 399 # +limit+ is the maximum number of documents to be returned. It defaults to
400 # 10. 400 # 10.
401 - def recent_documents(limit = 10, options = {})  
402 - self.articles.recent(limit, options) 401 + def recent_documents(limit = 10, options = {}, pagination = true)
  402 + self.articles.recent(limit, options, pagination)
403 end 403 end
404 404
405 def last_articles(limit = 10, options = {}) 405 def last_articles(limit = 10, options = {})
app/models/profile_list_block.rb
@@ -14,12 +14,13 @@ class ProfileListBlock < Block @@ -14,12 +14,13 @@ class ProfileListBlock < Block
14 14
15 def profile_list 15 def profile_list
16 result = nil 16 result = nil
  17 + visible_profiles = profiles.visible.includes([:image,:domains,:preferred_domain,:environment])
17 if !prioritize_profiles_with_image 18 if !prioritize_profiles_with_image
18 - result = profiles.visible.all(:limit => limit, :order => 'updated_at DESC').sort_by{ rand }  
19 - elsif profiles.visible.with_image.count >= limit  
20 - result = profiles.visible.with_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand } 19 + result = visible_profiles.all(:limit => limit, :order => 'updated_at DESC').sort_by{ rand }
  20 + elsif visible_profiles.with_image.count >= limit
  21 + result = visible_profiles.with_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand }
21 else 22 else
22 - result = profiles.visible.with_image.sort_by{ rand } + profiles.visible.without_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand } 23 + result = visible_profiles.with_image.sort_by{ rand } + visible_profiles.without_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand }
23 end 24 end
24 result.slice(0..limit-1) 25 result.slice(0..limit-1)
25 end 26 end
app/models/recent_documents_block.rb
@@ -16,11 +16,9 @@ class RecentDocumentsBlock < Block @@ -16,11 +16,9 @@ class RecentDocumentsBlock < Block
16 16
17 include ActionController::UrlWriter 17 include ActionController::UrlWriter
18 def content(args={}) 18 def content(args={})
19 - docs = self.limit.nil? ? owner.recent_documents : owner.recent_documents(self.limit)  
20 - 19 + docs = self.limit.nil? ? owner.recent_documents(nil, {}, false) : owner.recent_documents(self.limit, {}, false)
21 block_title(title) + 20 block_title(title) +
22 content_tag('ul', docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) 21 content_tag('ul', docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
23 -  
24 end 22 end
25 23
26 def footer 24 def footer
app/views/profile/_person_profile.rhtml
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 <tr> 37 <tr>
38 <th colspan='2'><%= __('Enterprises') %></th> 38 <th colspan='2'><%= __('Enterprises') %></th>
39 </tr> 39 </tr>
40 - <% profile.enterprises.each do |item| %> 40 + <% profile.enterprises.includes(:environment,:domains, :preferred_domain).each do |item| %>
41 <tr> 41 <tr>
42 <td></td> 42 <td></td>
43 <td><%= button 'menu-enterprise', item.name, item.url %></td> 43 <td><%= button 'menu-enterprise', item.name, item.url %></td>
lib/acts_as_having_boxes.rb
@@ -18,7 +18,7 @@ module ActsAsHavingBoxes @@ -18,7 +18,7 @@ module ActsAsHavingBoxes
18 @blocks = nil 18 @blocks = nil
19 end 19 end
20 if @blocks.nil? 20 if @blocks.nil?
21 - @blocks = boxes.inject([]) do |acc,obj| 21 + @blocks = boxes.includes(:blocks).inject([]) do |acc,obj|
22 acc.concat(obj.blocks) 22 acc.concat(obj.blocks)
23 end 23 end
24 @blocks.send(:extend, BlockArray) 24 @blocks.send(:extend, BlockArray)
vendor/plugins/access_control/lib/acts_as_accessor.rb
@@ -4,7 +4,7 @@ class ActiveRecord::Base @@ -4,7 +4,7 @@ class ActiveRecord::Base
4 4
5 def has_permission?(permission, resource = nil) 5 def has_permission?(permission, resource = nil)
6 return true if resource == self 6 return true if resource == self
7 - role_assignments.any? {|ra| ra.has_permission?(permission, resource)} 7 + role_assignments.includes([:resource,:role]).any? {|ra| ra.has_permission?(permission, resource)}
8 end 8 end
9 9
10 def define_roles(roles, resource) 10 def define_roles(roles, resource)