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 49  
50 50 def communities
51 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 53 end
54 54 end
55 55  
56 56 def enterprises
57   - @enterprises = profile.enterprises
  57 + @enterprises = profile.enterprises.includes(relations_to_include)
58 58 end
59 59  
60 60 def friends
61 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 63 end
64 64 end
65 65  
66 66 def members
67 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 69 end
70 70 end
71 71  
72 72 def fans
73   - @fans = profile.fans
  73 + @fans = profile.fans.includes(relations_to_include)
74 74 end
75 75  
76 76 def favorite_enterprises
77   - @favorite_enterprises = profile.favorite_enterprises
  77 + @favorite_enterprises = profile.favorite_enterprises.includes(relations_to_include)
78 78 end
79 79  
80 80 def sitemap
81   - @articles = profile.top_level_articles
  81 + @articles = profile.top_level_articles.includes([:profile, :parent])
82 82 end
83 83  
84 84 def join
... ... @@ -246,7 +246,7 @@ class ProfileController < PublicController
246 246  
247 247 def profile_info
248 248 begin
249   - @block = profile.blocks.find(params[:block_id])
  249 + @block = profile.blocks.find(params[:block_id]).includes(:box)
250 250 rescue
251 251 render :text => _('Profile information could not be loaded')
252 252 end
... ... @@ -359,4 +359,8 @@ class ProfileController < PublicController
359 359 @can_edit_profile ||= user && user.has_permission?('edit_profile', profile)
360 360 end
361 361 helper_method :can_edit_profile
  362 +
  363 + def relations_to_include
  364 + [:image, :domains, :preferred_domain, :environment]
  365 + end
362 366 end
... ...
app/controllers/public/search_controller.rb
... ... @@ -46,7 +46,7 @@ class SearchController < PublicController
46 46 if !@empty_query
47 47 full_text_search ['public:true']
48 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 50 end
51 51 end
52 52  
... ... @@ -76,7 +76,7 @@ class SearchController < PublicController
76 76 full_text_search ['public:true']
77 77 else
78 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 80 end
81 81 end
82 82  
... ... @@ -84,7 +84,7 @@ class SearchController < PublicController
84 84 if !@empty_query
85 85 full_text_search ['public:true']
86 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 88 end
89 89 end
90 90  
... ... @@ -310,4 +310,12 @@ class SearchController < PublicController
310 310 @all_facets = ret[:all_facets]
311 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 321 end
... ...
app/helpers/boxes_helper.rb
... ... @@ -66,7 +66,7 @@ module BoxesHelper
66 66  
67 67 def display_box_content(box, main_content)
68 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 70 end
71 71  
72 72 def select_blocks(arr, context)
... ...
app/models/article.rb
... ... @@ -179,37 +179,23 @@ class Article < ActiveRecord::Base
179 179 end
180 180  
181 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 196 end
  197 +
  198 + pagination ? result.paginate({:page => 1, :per_page => limit}) : result
213 199 end
214 200  
215 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 17 after_save_reindex [:products], :with => :delayed_job
18 18 extra_data_for_index :product_categories
19 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 21 end
22 22  
23 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 591 end
592 592  
593 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 596 end
597 597  
598 598 has_many :events, :through => :profiles, :source => :articles, :class_name => 'Event'
... ...
app/models/person.rb
... ... @@ -251,7 +251,7 @@ class Person < Profile
251 251  
252 252 def is_admin?(environment = nil)
253 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 255 ps.any? do |p|
256 256 ActiveRecord::Base::PERMISSIONS['Environment'].keys.include?(p)
257 257 end
... ...
app/models/profile.rb
... ... @@ -398,8 +398,8 @@ class Profile < ActiveRecord::Base
398 398 #
399 399 # +limit+ is the maximum number of documents to be returned. It defaults to
400 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 403 end
404 404  
405 405 def last_articles(limit = 10, options = {})
... ...
app/models/profile_list_block.rb
... ... @@ -14,12 +14,13 @@ class ProfileListBlock < Block
14 14  
15 15 def profile_list
16 16 result = nil
  17 + visible_profiles = profiles.visible.includes([:image,:domains,:preferred_domain,:environment])
17 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 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 24 end
24 25 result.slice(0..limit-1)
25 26 end
... ...
app/models/recent_documents_block.rb
... ... @@ -16,11 +16,9 @@ class RecentDocumentsBlock < Block
16 16  
17 17 include ActionController::UrlWriter
18 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 20 block_title(title) +
22 21 content_tag('ul', docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
23   -
24 22 end
25 23  
26 24 def footer
... ...
app/views/profile/_person_profile.rhtml
... ... @@ -37,7 +37,7 @@
37 37 <tr>
38 38 <th colspan='2'><%= __('Enterprises') %></th>
39 39 </tr>
40   - <% profile.enterprises.each do |item| %>
  40 + <% profile.enterprises.includes(:environment,:domains, :preferred_domain).each do |item| %>
41 41 <tr>
42 42 <td></td>
43 43 <td><%= button 'menu-enterprise', item.name, item.url %></td>
... ...
lib/acts_as_having_boxes.rb
... ... @@ -18,7 +18,7 @@ module ActsAsHavingBoxes
18 18 @blocks = nil
19 19 end
20 20 if @blocks.nil?
21   - @blocks = boxes.inject([]) do |acc,obj|
  21 + @blocks = boxes.includes(:blocks).inject([]) do |acc,obj|
22 22 acc.concat(obj.blocks)
23 23 end
24 24 @blocks.send(:extend, BlockArray)
... ...
vendor/plugins/access_control/lib/acts_as_accessor.rb
... ... @@ -4,7 +4,7 @@ class ActiveRecord::Base
4 4  
5 5 def has_permission?(permission, resource = nil)
6 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 8 end
9 9  
10 10 def define_roles(roles, resource)
... ...