Commit a0ef4f259127426b96f8a8ba2bbb2c18c67bf980

Authored by Victor Costa
2 parents 5c4d0723 a1ec80fb

Merge branch 'fix_lazy_queries' into stable

Conflicts:
	app/controllers/public/content_viewer_controller.rb
Gemfile
... ... @@ -24,6 +24,10 @@ gem 'locale', '~> 2.0.5'
24 24 # FIXME list here all actual dependencies (i.e. the ones in debian/control),
25 25 # with their GEM names (not the Debian package names)
26 26  
  27 +group :development do
  28 + gem 'bullet'
  29 +end
  30 +
27 31 group :production do
28 32 gem 'dalli', '~> 2.7.0'
29 33 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -59,7 +59,7 @@ class CmsController < MyProfileController
59 59 conditions = ['type != ?', 'RssFeed']
60 60 end
61 61  
62   - @articles = @article.children.reorder("case when type = 'Folder' then 0 when type ='Blog' then 1 else 2 end, updated_at DESC, name").paginate(
  62 + @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(
63 63 :conditions => conditions,
64 64 :per_page => per_page,
65 65 :page => params[:npage]
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -8,49 +8,32 @@ class ContentViewerController < ApplicationController
8 8 helper TagsHelper
9 9  
10 10 def view_page
11   - path = params[:page]
12   - path = path.join('/') if path.kind_of?(Array)
13   - path = "#{path}.#{params[:format]}" if params[:format]
  11 + path = get_path(params[:page], params[:format])
  12 +
14 13 @version = params[:version].to_i
15 14  
16 15 if path.blank?
17   - @page = profile.home_page
18   - if @page.nil?
19   - redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier
20   - return
21   - end
  16 + @page = profile.home_page
  17 + return if redirected_to_profile_index
22 18 else
23 19 @page = profile.articles.find_by_path(path)
24   - unless @page
25   - page_from_old_path = profile.articles.find_by_old_path(path)
26   - if page_from_old_path
27   - redirect_to profile.url.merge(:page => page_from_old_path.explode_path)
28   - return
29   - end
30   - end
  20 + return if redirected_page_from_old_path(path)
31 21 end
32 22  
33 23 return unless allow_access_to_page(path)
34 24  
35 25 if @version > 0
36 26 return render_access_denied unless @page.display_versions?
37   - @versioned_article = @page.versions.find_by_version(@version)
38   - if @versioned_article && @page.versions.latest.version != @versioned_article.version
39   - render :template => 'content_viewer/versioned_article.html.erb'
40   - return
41   - end
  27 + return if rendered_versioned_article
42 28 end
43 29  
44 30 redirect_to_translation and return if @page.profile.redirect_l10n
45 31  
46   - if request.post?
47   - if @page.forum? && @page.has_terms_of_use && params[:terms_accepted] == "true"
48   - @page.add_agreed_user(user)
49   - end
50   - elsif !@page.parent.nil? && @page.parent.forum?
51   - unless @page.parent.agrees_with_terms?(user)
52   - redirect_to @page.parent.url
53   - end
  32 + if request.post? && @page.forum?
  33 + process_forum_terms_of_use(user, params[:terms_accepted])
  34 + elsif is_a_forum_topic?(@page) && !@page.parent.agrees_with_terms?(user)
  35 + redirect_to @page.parent.url
  36 + return
54 37 end
55 38  
56 39 # At this point the page will be showed
... ... @@ -58,64 +41,22 @@ class ContentViewerController < ApplicationController
58 41  
59 42 @page = FilePresenter.for @page
60 43  
61   - if @page.download? params[:view]
62   - headers['Content-Type'] = @page.mime_type
63   - headers.merge! @page.download_headers
64   - data = @page.data
65   -
66   - # TODO test the condition
67   - if data.nil?
68   - raise "No data for file"
69   - end
70   -
71   - render :text => data, :layout => false
72   - return
73   - end
  44 + return if rendered_file_download(params[:view])
74 45  
75 46 @form_div = params[:form]
76 47  
77 48 #FIXME see a better way to do this. It's not need to pass this variable anymore
78 49 @comment = Comment.new
79 50  
80   - if @page.has_posts?
81   - posts = if params[:year] and params[:month]
82   - filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01")
83   - @page.posts.by_range(filter_date..filter_date.at_end_of_month)
84   - else
85   - @page.posts
86   - end
87   -
88   - #FIXME Need to run this before the pagination because this version of
89   - # will_paginate returns a will_paginate collection instead of a
90   - # relation.
91   - blog_with_translation = @page.blog? && @page.display_posts_in_current_language?
92   - posts = posts.native_translations if blog_with_translation
93   -
94   - @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))).to_a
95   -
96   - if blog_with_translation
97   - @posts.replace @posts.map{ |p| p.get_translation_to(FastGettext.locale) }.compact
98   - end
99   - end
  51 + process_page_posts(params)
100 52  
101 53 if @page.folder? && @page.gallery?
102   - @images = @page.images.select{ |a| a.display_to? user }
103   - @images = @images.paginate(:per_page => per_page, :page => params[:npage]) unless params[:slideshow]
  54 + @images = get_images(@page, params[:npage], params[:slideshow])
104 55 end
105 56  
106   - @unfollow_form = params[:unfollow] && params[:unfollow] == 'true'
107   - if params[:unfollow] && params[:unfollow] == 'commit' && request.post?
108   - @page.followers -= [params[:email]]
109   - if @page.save
110   - session[:notice] = _("Notification of new comments to '%s' was successfully canceled") % params[:email]
111   - end
112   - end
  57 + process_page_followers(params)
113 58  
114   - @comments = @page.comments.without_spam
115   - @comments = @plugins.filter(:unavailable_comments, @comments)
116   - @comments_count = @comments.count
117   - @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] )
118   - @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
  59 + process_comments(params)
119 60  
120 61 if request.xhr? and params[:comment_order]
121 62 if @comment_order == 'newest'
... ... @@ -129,11 +70,11 @@ class ContentViewerController < ApplicationController
129 70 render :action => 'slideshow', :layout => 'slideshow'
130 71 return
131 72 end
132   - render @page.view_page, :formats => [:html]
  73 + render :view_page, :formats => [:html]
133 74 end
134 75  
135 76 def versions_diff
136   - path = params[:page].join('/')
  77 + path = params[:page]
137 78 @page = profile.articles.find_by_path(path)
138 79 @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2])
139 80 end
... ... @@ -203,4 +144,127 @@ class ContentViewerController < ApplicationController
203 144 user_agent.match(/crawler/) ||
204 145 user_agent.match(/\(.*https?:\/\/.*\)/)
205 146 end
  147 +
  148 + def get_path(page, format = nil)
  149 + path = page
  150 + path = path.join('/') if path.kind_of?(Array)
  151 + path = "#{path}.#{format}" if format
  152 +
  153 + return path
  154 + end
  155 +
  156 + def redirected_to_profile_index
  157 + if @page.nil?
  158 + redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier
  159 + return true
  160 + end
  161 +
  162 + return false
  163 + end
  164 +
  165 + def redirected_page_from_old_path(path)
  166 + unless @page
  167 + page_from_old_path = profile.articles.find_by_old_path(path)
  168 + if page_from_old_path
  169 + redirect_to profile.url.merge(:page => page_from_old_path.explode_path)
  170 + return true
  171 + end
  172 + end
  173 +
  174 + return false
  175 + end
  176 +
  177 + def process_forum_terms_of_use(user, terms_accepted = nil)
  178 + if @page.forum? && @page.has_terms_of_use && terms_accepted == "true"
  179 + @page.add_agreed_user(user)
  180 + end
  181 + end
  182 +
  183 + def is_a_forum_topic? (page)
  184 + return (!@page.parent.nil? && @page.parent.forum?)
  185 + end
  186 +
  187 + def rendered_versioned_article
  188 + @versioned_article = @page.versions.find_by_version(@version)
  189 + if @versioned_article && @page.versions.latest.version != @versioned_article.version
  190 + render :template => 'content_viewer/versioned_article.html.erb'
  191 + return true
  192 + end
  193 +
  194 + return false
  195 + end
  196 +
  197 + def rendered_file_download(view = nil)
  198 + if @page.download? view
  199 + headers['Content-Type'] = @page.mime_type
  200 + headers.merge! @page.download_headers
  201 + data = @page.data
  202 +
  203 + # TODO test the condition
  204 + if data.nil?
  205 + raise "No data for file"
  206 + end
  207 +
  208 + render :text => data, :layout => false
  209 + return true
  210 + end
  211 +
  212 + return false
  213 + end
  214 +
  215 + def process_page_posts(params)
  216 + if @page.has_posts?
  217 + posts = get_posts(params[:year], params[:month])
  218 +
  219 + #FIXME Need to run this before the pagination because this version of
  220 + # will_paginate returns a will_paginate collection instead of a
  221 + # relation.
  222 + posts = posts.native_translations if blog_with_translation?(@page)
  223 +
  224 + @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))).includes(:author).to_a
  225 +
  226 + if blog_with_translation?(@page)
  227 + @posts.replace @posts.map{ |p| p.get_translation_to(FastGettext.locale) }.compact
  228 + end
  229 + end
  230 + end
  231 +
  232 + def get_posts(year = nil, month = nil)
  233 + if year && month
  234 + filter_date = DateTime.parse("#{year}-#{month}-01")
  235 + return @page.posts.by_range(filter_date..filter_date.at_end_of_month)
  236 + else
  237 + return @page.posts
  238 + end
  239 + end
  240 +
  241 + def blog_with_translation?(page)
  242 + return (page.blog? && page.display_posts_in_current_language?)
  243 + end
  244 +
  245 + def get_images(page, npage, slideshow)
  246 + images = page.images.select{ |a| a.display_to? user }
  247 + images = images.paginate(:per_page => per_page, :page => npage) unless slideshow
  248 +
  249 + return images
  250 + end
  251 +
  252 + def process_page_followers(params)
  253 + @unfollow_form = params[:unfollow] == 'true'
  254 + if params[:unfollow] == 'commit' && request.post?
  255 + @page.followers -= [params[:email]]
  256 + if @page.save
  257 + session[:notice] = _("Notification of new comments to '%s' was successfully canceled") % params[:email]
  258 + end
  259 + end
  260 + end
  261 +
  262 + def process_comments(params)
  263 + @comments = @page.comments.without_spam.includes(:source)
  264 + @comments = @plugins.filter(:unavailable_comments, @comments)
  265 + @comments_count = @comments.count
  266 + @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] )
  267 + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
  268 + end
  269 +
206 270 end
... ...
app/models/article.rb
... ... @@ -58,10 +58,10 @@ class Article < ActiveRecord::Base
58 58 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
59 59 belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id'
60 60  
61   - has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc'
  61 + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'comments.created_at asc', :include => [:author, :children]
62 62  
63 63 has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ]
64   - has_many :categories, :through => :article_categorizations
  64 + has_many :categories, :through => :article_categorizations, :include => [:environment]
65 65  
66 66 has_many :article_categorizations_including_virtual, :class_name => 'ArticleCategorization'
67 67 has_many :categories_including_virtual, :through => :article_categorizations_including_virtual, :source => :category
... ... @@ -251,7 +251,7 @@ class Article < ActiveRecord::Base
251 251 # retrieves all articles belonging to the given +profile+ that are not
252 252 # sub-articles of any other article.
253 253 scope :top_level_for, lambda { |profile|
254   - {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ]}
  254 + {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ], :include => [:profile]}
255 255 }
256 256  
257 257 scope :public,
... ... @@ -475,7 +475,7 @@ class Article < ActiveRecord::Base
475 475 end
476 476  
477 477 scope :published, :conditions => ['articles.published = ?', true]
478   - scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }}
  478 + scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types], :include => [:parent] }}
479 479 scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}}
480 480 scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ]
481 481 scope :images, :conditions => { :is_image => true }
... ... @@ -484,7 +484,7 @@ class Article < ActiveRecord::Base
484 484  
485 485 scope :more_popular, :order => 'hits DESC'
486 486 scope :more_comments, :order => "comments_count DESC"
487   - scope :more_recent, :order => "created_at DESC"
  487 + scope :more_recent, :order => "articles.created_at DESC"
488 488  
489 489 def self.display_filter(user, profile)
490 490 return {:conditions => ['articles.published = ?', true]} if !user
... ...
app/models/category.rb
... ... @@ -16,7 +16,7 @@ class Category < ActiveRecord::Base
16 16  
17 17 # Finds all top level categories for a given environment.
18 18 scope :top_level_for, lambda { |environment|
19   - {:conditions => ['parent_id is null and environment_id = ?', environment.id ]}
  19 + {:conditions => ['parent_id is null and environment_id = ?', environment.id ], :include => [:children]}
20 20 }
21 21  
22 22 scope :on_level, lambda { |parent| {:conditions => {:parent_id => parent}} }
... ...
app/models/comment.rb
... ... @@ -18,7 +18,7 @@ class Comment < ActiveRecord::Base
18 18 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy
19 19 belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id'
20 20  
21   - scope :without_reply, :conditions => ['reply_of_id IS NULL']
  21 + scope :without_reply, :conditions => ['comments.reply_of_id IS NULL']
22 22  
23 23 #FIXME make this test
24 24 scope :newer_than, lambda { |reference_id|
... ...
app/models/person.rb
... ... @@ -434,7 +434,7 @@ class Person < Profile
434 434 end
435 435  
436 436 def already_reported?(profile)
437   - abuse_reports.any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? }
  437 + abuse_reports.includes({:abuse_complaint => :reported}).any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? }
438 438 end
439 439  
440 440 def register_report(abuse_report, profile)
... ...
app/models/profile.rb
... ... @@ -228,7 +228,7 @@ class Profile < ActiveRecord::Base
228 228 belongs_to :preferred_domain, :class_name => 'Domain', :foreign_key => 'preferred_domain_id'
229 229 belongs_to :environment
230 230  
231   - has_many :articles, :dependent => :destroy
  231 + has_many :articles, :dependent => :destroy, :include => [:profile]
232 232 belongs_to :home_page, :class_name => Article.name, :foreign_key => 'home_page_id'
233 233  
234 234 has_many :files, :class_name => 'UploadedFile'
... ...
config/environments/development.rb
... ... @@ -35,4 +35,10 @@ Noosfero::Application.configure do
35 35 config.assets.debug = true
36 36  
37 37 config.consider_all_requests_local = true
  38 +
  39 + config.after_initialize do
  40 + Bullet.enable = true
  41 + Bullet.console = true
  42 + end
  43 +
38 44 end
... ...
lib/acts_as_having_posts.rb
... ... @@ -2,7 +2,7 @@ module ActsAsHavingPosts
2 2  
3 3 module ClassMethods
4 4 def acts_as_having_posts(options = {})
5   - has_many :posts, { :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'articles.type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC' }.merge(options)
  5 + 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)
6 6  
7 7 attr_accessor :feed_attrs
8 8  
... ...
lib/spammable.rb
... ... @@ -12,8 +12,8 @@ module Spammable
12 12 def self.extended (base)
13 13 if base.respond_to?(:scope)
14 14 base.class_eval do
15   - scope :without_spam, :conditions => ['spam IS NULL OR spam = ?', false]
16   - scope :spam, :conditions => ['spam = ?', true]
  15 + scope :without_spam, :conditions => ["#{base.table_name}.spam IS NULL OR #{base.table_name}.spam = ?", false]
  16 + scope :spam, :conditions => ["#{base.table_name}.spam = ?", true]
17 17 end
18 18 end
19 19 end
... ...