Commit 4bbfef7e42eff51025675d1e6f70aee7c26527ff
1 parent
457c9f59
Exists in
master
and in
29 other branches
article: author refactoring
I'm adding the author as a record relation instead of calculating it based on the last_changed_by. This change has a reasonable performance improvement on pages that access this information, like blog page. Still saving author_name in order to deal with the problem of the author being removed. Including new method to facilitate specific article version retrieval. ActionItem3201
Showing
8 changed files
with
82 additions
and
38 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -144,6 +144,7 @@ class CmsController < MyProfileController | @@ -144,6 +144,7 @@ class CmsController < MyProfileController | ||
144 | end | 144 | end |
145 | 145 | ||
146 | @article.profile = profile | 146 | @article.profile = profile |
147 | + @article.author = user | ||
147 | @article.last_changed_by = user | 148 | @article.last_changed_by = user |
148 | 149 | ||
149 | translations if @article.translatable? | 150 | translations if @article.translatable? |
app/controllers/public/content_viewer_controller.rb
@@ -83,7 +83,7 @@ class ContentViewerController < ApplicationController | @@ -83,7 +83,7 @@ class ContentViewerController < ApplicationController | ||
83 | @page.posts | 83 | @page.posts |
84 | end | 84 | end |
85 | 85 | ||
86 | - posts = posts.includes(:parent, {:profile => [:domains, :environment]}) | 86 | + posts = posts.includes(:parent, {:profile => [:domains, :environment]}, :author) |
87 | 87 | ||
88 | #FIXME Need to run this before the pagination because this version of | 88 | #FIXME Need to run this before the pagination because this version of |
89 | # will_paginate returns a will_paginate collection instead of a | 89 | # will_paginate returns a will_paginate collection instead of a |
app/helpers/content_viewer_helper.rb
@@ -26,7 +26,7 @@ module ContentViewerHelper | @@ -26,7 +26,7 @@ module ContentViewerHelper | ||
26 | end | 26 | end |
27 | title << content_tag('span', | 27 | title << content_tag('span', |
28 | content_tag('span', show_date(article.published_at), :class => 'date') + | 28 | content_tag('span', show_date(article.published_at), :class => 'date') + |
29 | - content_tag('span', [_(", by %s") % link_to(article.author_name, article.author_url)], :class => 'author') + | 29 | + content_tag('span', [_(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name)], :class => 'author') + |
30 | content_tag('span', comments, :class => 'comments'), | 30 | content_tag('span', comments, :class => 'comments'), |
31 | :class => 'created-at' | 31 | :class => 'created-at' |
32 | ) | 32 | ) |
app/models/article.rb
@@ -39,8 +39,8 @@ class Article < ActiveRecord::Base | @@ -39,8 +39,8 @@ class Article < ActiveRecord::Base | ||
39 | before_save :sanitize_tag_list | 39 | before_save :sanitize_tag_list |
40 | 40 | ||
41 | before_create do |article| | 41 | before_create do |article| |
42 | - if article.last_changed_by_id | ||
43 | - article.author_name = Person.find(article.last_changed_by_id).name | 42 | + if article.author |
43 | + article.author_name = article.author.name | ||
44 | end | 44 | end |
45 | end | 45 | end |
46 | 46 | ||
@@ -52,6 +52,7 @@ class Article < ActiveRecord::Base | @@ -52,6 +52,7 @@ class Article < ActiveRecord::Base | ||
52 | 52 | ||
53 | validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } | 53 | validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } |
54 | 54 | ||
55 | + belongs_to :author, :class_name => 'Person' | ||
55 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' | 56 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' |
56 | 57 | ||
57 | has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' | 58 | has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' |
@@ -449,7 +450,7 @@ class Article < ActiveRecord::Base | @@ -449,7 +450,7 @@ class Article < ActiveRecord::Base | ||
449 | ['TextArticle', 'TextileArticle', 'TinyMceArticle'] | 450 | ['TextArticle', 'TextileArticle', 'TinyMceArticle'] |
450 | end | 451 | end |
451 | 452 | ||
452 | - named_scope :published, :conditions => { :published => true } | 453 | + named_scope :published, :conditions => ['articles.published = ?', true] |
453 | named_scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }} | 454 | named_scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }} |
454 | named_scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}} | 455 | named_scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}} |
455 | named_scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ] | 456 | named_scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ] |
@@ -462,7 +463,7 @@ class Article < ActiveRecord::Base | @@ -462,7 +463,7 @@ class Article < ActiveRecord::Base | ||
462 | named_scope :more_recent, :order => "created_at DESC" | 463 | named_scope :more_recent, :order => "created_at DESC" |
463 | 464 | ||
464 | def self.display_filter(user, profile) | 465 | def self.display_filter(user, profile) |
465 | - return {:conditions => ['published = ?', true]} if !user | 466 | + return {:conditions => ['articles.published = ?', true]} if !user |
466 | {:conditions => [" articles.published = ? OR | 467 | {:conditions => [" articles.published = ? OR |
467 | articles.last_changed_by_id = ? OR | 468 | articles.last_changed_by_id = ? OR |
468 | articles.profile_id = ? OR | 469 | articles.profile_id = ? OR |
@@ -621,39 +622,36 @@ class Article < ActiveRecord::Base | @@ -621,39 +622,36 @@ class Article < ActiveRecord::Base | ||
621 | can_display_versions? && display_versions | 622 | can_display_versions? && display_versions |
622 | end | 623 | end |
623 | 624 | ||
624 | - def author(version_number = nil) | ||
625 | - if version_number | ||
626 | - version = versions.find_by_version(version_number) | ||
627 | - author_id = version.last_changed_by_id if version | ||
628 | - Person.exists?(author_id) ? Person.find(author_id) : nil | ||
629 | - else | ||
630 | - if versions.empty? | ||
631 | - last_changed_by | ||
632 | - else | ||
633 | - author_id = versions.first.last_changed_by_id | ||
634 | - Person.exists?(author_id) ? Person.find(author_id) : nil | ||
635 | - end | ||
636 | - end | 625 | + def get_version(version_number = nil) |
626 | + version_number ? versions.find(:first, :order => 'version', :offset => version_number - 1) : versions.earliest | ||
627 | + end | ||
628 | + | ||
629 | + def author_by_version(version_number = nil) | ||
630 | + version_number ? profile.environment.people.find_by_id(get_version(version_number).last_changed_by_id) : author | ||
637 | end | 631 | end |
638 | 632 | ||
639 | def author_name(version_number = nil) | 633 | def author_name(version_number = nil) |
640 | - person = author(version_number) | ||
641 | - person ? person.name : (setting[:author_name] || _('Unknown')) | 634 | + person = author_by_version(version_number) |
635 | + if version_number | ||
636 | + person ? person.name : _('Unknown') | ||
637 | + else | ||
638 | + person ? person.name : (setting[:author_name] || _('Unknown')) | ||
639 | + end | ||
642 | end | 640 | end |
643 | 641 | ||
644 | def author_url(version_number = nil) | 642 | def author_url(version_number = nil) |
645 | - person = author(version_number) | 643 | + person = author_by_version(version_number) |
646 | person ? person.url : nil | 644 | person ? person.url : nil |
647 | end | 645 | end |
648 | 646 | ||
649 | def author_id(version_number = nil) | 647 | def author_id(version_number = nil) |
650 | - person = author(version_number) | 648 | + person = author_by_version(version_number) |
651 | person ? person.id : nil | 649 | person ? person.id : nil |
652 | end | 650 | end |
653 | 651 | ||
654 | def version_license(version_number = nil) | 652 | def version_license(version_number = nil) |
655 | return license if version_number.nil? | 653 | return license if version_number.nil? |
656 | - profile.environment.licenses.find_by_id(versions.find_by_version(version_number).license_id) | 654 | + profile.environment.licenses.find_by_id(get_version(version_number).license_id) |
657 | end | 655 | end |
658 | 656 | ||
659 | alias :active_record_cache_key :cache_key | 657 | alias :active_record_cache_key :cache_key |
db/migrate/20140709224246_create_real_relation_between_article_and_author.rb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class CreateRealRelationBetweenArticleAndAuthor < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + add_column :articles, :author_id, :integer | ||
4 | + add_column :article_versions, :author_id, :integer | ||
5 | + | ||
6 | + # Set article's author as the first version's last_changed_by_id. | ||
7 | + execute "update articles set author_id = (select article_versions.last_changed_by_id from article_versions where article_versions.article_id = articles.id and article_versions.version = 1 limit 1)" | ||
8 | + end | ||
9 | + | ||
10 | + def self.down | ||
11 | + remove_column :articles, :author_id | ||
12 | + remove_column :article_versions, :author_id | ||
13 | + end | ||
14 | +end |
db/schema.rb
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | # | 9 | # |
10 | # It's strongly recommended to check this file into your version control system. | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | ||
12 | -ActiveRecord::Schema.define(:version => 20140709212646) do | 12 | +ActiveRecord::Schema.define(:version => 20140709224246) do |
13 | 13 | ||
14 | create_table "abuse_reports", :force => true do |t| | 14 | create_table "abuse_reports", :force => true do |t| |
15 | t.integer "reporter_id" | 15 | t.integer "reporter_id" |
@@ -94,6 +94,7 @@ ActiveRecord::Schema.define(:version => 20140709212646) do | @@ -94,6 +94,7 @@ ActiveRecord::Schema.define(:version => 20140709212646) do | ||
94 | t.integer "image_id" | 94 | t.integer "image_id" |
95 | t.integer "position" | 95 | t.integer "position" |
96 | t.integer "spam_comments_count", :default => 0 | 96 | t.integer "spam_comments_count", :default => 0 |
97 | + t.integer "author_id" | ||
97 | end | 98 | end |
98 | 99 | ||
99 | add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id" | 100 | add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id" |
@@ -140,6 +141,7 @@ ActiveRecord::Schema.define(:version => 20140709212646) do | @@ -140,6 +141,7 @@ ActiveRecord::Schema.define(:version => 20140709212646) do | ||
140 | t.integer "image_id" | 141 | t.integer "image_id" |
141 | t.integer "position" | 142 | t.integer "position" |
142 | t.integer "spam_comments_count", :default => 0 | 143 | t.integer "spam_comments_count", :default => 0 |
144 | + t.integer "author_id" | ||
143 | end | 145 | end |
144 | 146 | ||
145 | add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count" | 147 | add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count" |
test/functional/content_viewer_controller_test.rb
@@ -767,7 +767,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -767,7 +767,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
767 | c = Community.create!(:name => 'test_com') | 767 | c = Community.create!(:name => 'test_com') |
768 | u = create_user_with_permission('test_user', 'publish_content', c) | 768 | u = create_user_with_permission('test_user', 'publish_content', c) |
769 | login_as u.identifier | 769 | login_as u.identifier |
770 | - a = c.articles.create!(:name => 'test-article', :last_changed_by => u, :published => false) | 770 | + a = c.articles.create!(:name => 'test-article', :author => u, :published => false) |
771 | 771 | ||
772 | get :view_page, :profile => c.identifier, :page => a.explode_path | 772 | get :view_page, :profile => c.identifier, :page => a.explode_path |
773 | 773 | ||
@@ -779,7 +779,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -779,7 +779,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
779 | c = Community.create!(:name => 'test_com') | 779 | c = Community.create!(:name => 'test_com') |
780 | u = create_user_with_permission('test_user', 'publish_content', c) | 780 | u = create_user_with_permission('test_user', 'publish_content', c) |
781 | login_as u.identifier | 781 | login_as u.identifier |
782 | - a = c.articles.create!(:name => 'test-article', :last_changed_by => profile, :published => true) | 782 | + a = c.articles.create!(:name => 'test-article', :author => profile, :published => true) |
783 | 783 | ||
784 | xhr :get, :view_page, :profile => c.identifier, :page => a.explode_path, :toolbar => true | 784 | xhr :get, :view_page, :profile => c.identifier, :page => a.explode_path, :toolbar => true |
785 | 785 | ||
@@ -926,7 +926,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -926,7 +926,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
926 | community.add_member(author) | 926 | community.add_member(author) |
927 | 927 | ||
928 | forum = Forum.create(:profile => community, :name => 'Forum test', :body => 'Forum test') | 928 | forum = Forum.create(:profile => community, :name => 'Forum test', :body => 'Forum test') |
929 | - post = fast_create(TextileArticle, :name => 'First post', :profile_id => community.id, :parent_id => forum.id, :last_changed_by_id => author.id) | 929 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => community.id, :parent_id => forum.id, :author_id => author.id) |
930 | 930 | ||
931 | login_as(author.identifier) | 931 | login_as(author.identifier) |
932 | get :view_page, :profile => community.identifier, :page => post.path.split('/') | 932 | get :view_page, :profile => community.identifier, :page => post.path.split('/') |
@@ -942,7 +942,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -942,7 +942,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
942 | community.add_member(author) | 942 | community.add_member(author) |
943 | 943 | ||
944 | forum = Forum.create(:profile => community, :name => 'Forum test', :body => 'Forum test') | 944 | forum = Forum.create(:profile => community, :name => 'Forum test', :body => 'Forum test') |
945 | - post = fast_create(TextileArticle, :name => 'First post', :profile_id => community.id, :parent_id => forum.id, :last_changed_by_id => author.id) | 945 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => community.id, :parent_id => forum.id, :author_id => author.id) |
946 | 946 | ||
947 | login_as(author.identifier) | 947 | login_as(author.identifier) |
948 | get :view_page, :profile => community.identifier, :page => post.path.split('/') | 948 | get :view_page, :profile => community.identifier, :page => post.path.split('/') |
test/unit/article_test.rb
@@ -802,7 +802,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -802,7 +802,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
802 | should 'allow author to edit if is publisher' do | 802 | should 'allow author to edit if is publisher' do |
803 | c = fast_create(Community) | 803 | c = fast_create(Community) |
804 | p = create_user_with_permission('test_user', 'publish_content', c) | 804 | p = create_user_with_permission('test_user', 'publish_content', c) |
805 | - a = c.articles.create!(:name => 'a test article', :last_changed_by => p) | 805 | + a = c.articles.create!(:name => 'a test article', :author => p) |
806 | 806 | ||
807 | assert a.allow_post_content?(p) | 807 | assert a.allow_post_content?(p) |
808 | end | 808 | end |
@@ -1378,7 +1378,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1378,7 +1378,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
1378 | 1378 | ||
1379 | should "the author_name returns the name of the article's author" do | 1379 | should "the author_name returns the name of the article's author" do |
1380 | author = fast_create(Person) | 1380 | author = fast_create(Person) |
1381 | - a = profile.articles.create!(:name => 'a test article', :last_changed_by => author) | 1381 | + a = profile.articles.create!(:name => 'a test article', :author => author) |
1382 | assert_equal author.name, a.author_name | 1382 | assert_equal author.name, a.author_name |
1383 | author.destroy | 1383 | author.destroy |
1384 | a.reload | 1384 | a.reload |
@@ -1388,7 +1388,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1388,7 +1388,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
1388 | 1388 | ||
1389 | should 'retrieve latest info from topic when has no comments' do | 1389 | should 'retrieve latest info from topic when has no comments' do |
1390 | forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) | 1390 | forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) |
1391 | - post = fast_create(TextileArticle, :name => 'First post', :profile_id => profile.id, :parent_id => forum.id, :updated_at => Time.now, :last_changed_by_id => profile.id) | 1391 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => profile.id, :parent_id => forum.id, :updated_at => Time.now, :author_id => profile.id) |
1392 | assert_equal post.updated_at, post.info_from_last_update[:date] | 1392 | assert_equal post.updated_at, post.info_from_last_update[:date] |
1393 | assert_equal profile.name, post.info_from_last_update[:author_name] | 1393 | assert_equal profile.name, post.info_from_last_update[:author_name] |
1394 | assert_equal profile.url, post.info_from_last_update[:author_url] | 1394 | assert_equal profile.url, post.info_from_last_update[:author_url] |
@@ -1668,7 +1668,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1668,7 +1668,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
1668 | author = fast_create(Person) | 1668 | author = fast_create(Person) |
1669 | community.add_member(author) | 1669 | community.add_member(author) |
1670 | forum = Forum.create(:profile => community, :name => 'Forum test', :body => 'Forum test') | 1670 | forum = Forum.create(:profile => community, :name => 'Forum test', :body => 'Forum test') |
1671 | - post = fast_create(TextileArticle, :name => 'First post', :profile_id => community.id, :parent_id => forum.id, :last_changed_by_id => author.id) | 1671 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => community.id, :parent_id => forum.id, :author_id => author.id) |
1672 | 1672 | ||
1673 | assert post.allow_edit?(author) | 1673 | assert post.allow_edit?(author) |
1674 | end | 1674 | end |
@@ -1753,7 +1753,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1753,7 +1753,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
1753 | 1753 | ||
1754 | should 'set author_name before creating article if there is an author' do | 1754 | should 'set author_name before creating article if there is an author' do |
1755 | author = fast_create(Person) | 1755 | author = fast_create(Person) |
1756 | - article = Article.create!(:name => 'Test', :profile => profile, :last_changed_by => author) | 1756 | + article = Article.create!(:name => 'Test', :profile => profile, :author => author) |
1757 | assert_equal author.name, article.author_name | 1757 | assert_equal author.name, article.author_name |
1758 | 1758 | ||
1759 | author_name = author.name | 1759 | author_name = author.name |
@@ -1764,12 +1764,12 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1764,12 +1764,12 @@ class ArticleTest < ActiveSupport::TestCase | ||
1764 | 1764 | ||
1765 | should "author_id return the author id of the article's author" do | 1765 | should "author_id return the author id of the article's author" do |
1766 | author = fast_create(Person) | 1766 | author = fast_create(Person) |
1767 | - article = Article.create!(:name => 'Test', :profile => profile, :last_changed_by => author) | 1767 | + article = Article.create!(:name => 'Test', :profile => profile, :author => author) |
1768 | assert_equal author.id, article.author_id | 1768 | assert_equal author.id, article.author_id |
1769 | end | 1769 | end |
1770 | 1770 | ||
1771 | should "author_id return nil if there is no article's author" do | 1771 | should "author_id return nil if there is no article's author" do |
1772 | - article = Article.create!(:name => 'Test', :profile => profile, :last_changed_by => nil) | 1772 | + article = Article.create!(:name => 'Test', :profile => profile, :author => nil) |
1773 | assert_nil article.author_id | 1773 | assert_nil article.author_id |
1774 | end | 1774 | end |
1775 | 1775 | ||
@@ -1780,8 +1780,8 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1780,8 +1780,8 @@ class ArticleTest < ActiveSupport::TestCase | ||
1780 | article.name = 'second version' | 1780 | article.name = 'second version' |
1781 | article.last_changed_by = author2 | 1781 | article.last_changed_by = author2 |
1782 | article.save | 1782 | article.save |
1783 | - assert_equal author1, article.author(1) | ||
1784 | - assert_equal author2, article.author(2) | 1783 | + assert_equal author1, article.author_by_version(1) |
1784 | + assert_equal author2, article.author_by_version(2) | ||
1785 | end | 1785 | end |
1786 | 1786 | ||
1787 | should "return the author_name of a specific version" do | 1787 | should "return the author_name of a specific version" do |
@@ -1837,4 +1837,33 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1837,4 +1837,33 @@ class ArticleTest < ActiveSupport::TestCase | ||
1837 | assert_equivalent [c3], Article.with_types(['Event']) | 1837 | assert_equivalent [c3], Article.with_types(['Event']) |
1838 | end | 1838 | end |
1839 | 1839 | ||
1840 | + should 'get specific version' do | ||
1841 | + article = Article.create!(:name => 'first version', :profile => profile) | ||
1842 | + article.name = 'second version' | ||
1843 | + article.save! | ||
1844 | + article.name = 'third version' | ||
1845 | + article.save! | ||
1846 | + | ||
1847 | + assert_equal 'first version', article.get_version(1).name | ||
1848 | + assert_equal 'second version', article.get_version(2).name | ||
1849 | + assert_equal 'third version', article.get_version(3).name | ||
1850 | + end | ||
1851 | + | ||
1852 | + should 'get author by version' do | ||
1853 | + p1 = fast_create(Person) | ||
1854 | + p2 = fast_create(Person) | ||
1855 | + p3 = fast_create(Person) | ||
1856 | + article = Article.create!(:name => 'first version', :profile => profile, :last_changed_by => p1) | ||
1857 | + article.name = 'second version' | ||
1858 | + article.last_changed_by = p2 | ||
1859 | + article.save! | ||
1860 | + article.last_changed_by = p3 | ||
1861 | + article.name = 'third version' | ||
1862 | + article.save! | ||
1863 | + | ||
1864 | + assert_equal p1, article.author_by_version(1) | ||
1865 | + assert_equal p2, article.author_by_version(2) | ||
1866 | + assert_equal p3, article.author_by_version(3) | ||
1867 | + end | ||
1868 | + | ||
1840 | end | 1869 | end |