diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb index 1c5696304..7b6dc8fa1 100644 --- a/app/controllers/debates_controller.rb +++ b/app/controllers/debates_controller.rb @@ -21,8 +21,8 @@ class DebatesController < ApplicationController @root_comments = @debate.comments.roots.recent.page(params[:page]).per(10).for_render @comments = @root_comments.inject([]){|all, root| all + root.descendants} - all_visible_comments = @root_comments + @comments - set_comment_flags(all_visible_comments) + @all_visible_comments = @root_comments + @comments + set_comment_flags(@all_visible_comments) end def new diff --git a/app/helpers/cache_keys_helper.rb b/app/helpers/cache_keys_helper.rb index 38445ae02..f75a21a59 100644 --- a/app/helpers/cache_keys_helper.rb +++ b/app/helpers/cache_keys_helper.rb @@ -12,6 +12,8 @@ module CacheKeysHelper user_status += ":signed" user_status += ":verified" if current_user.verified_at.present? user_status += ":org" if current_user.organization? + user_status += ":admin" if current_user.administrator? + user_status += ":moderator" if current_user.moderator? else user_status += ":visitor" end diff --git a/app/models/administrator.rb b/app/models/administrator.rb index 15715a328..8a34fa349 100644 --- a/app/models/administrator.rb +++ b/app/models/administrator.rb @@ -1,5 +1,5 @@ class Administrator < ActiveRecord::Base - belongs_to :user + belongs_to :user, touch: true delegate :name, :email, to: :user validates :user_id, presence: true, uniqueness: true diff --git a/app/models/comment.rb b/app/models/comment.rb index 8dd922714..efa9ec7a0 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -13,7 +13,7 @@ class Comment < ActiveRecord::Base belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true belongs_to :user, -> { with_hidden } - has_many :flags, :as => :flaggable + has_many :flags, as: :flaggable scope :recent, -> { order(id: :desc) } diff --git a/app/models/debate.rb b/app/models/debate.rb index 8471be20d..5e2864767 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -9,8 +9,8 @@ class Debate < ActiveRecord::Base include ActsAsParanoidAliases belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' - has_many :flags, :as => :flaggable has_many :comments, as: :commentable + has_many :flags, as: :flaggable validates :title, presence: true validates :description, presence: true diff --git a/app/models/flag.rb b/app/models/flag.rb index 2d13d26d9..02b16b385 100644 --- a/app/models/flag.rb +++ b/app/models/flag.rb @@ -22,6 +22,7 @@ class Flag < ActiveRecord::Base end def self.flagged?(user, flaggable) + return false unless user !! by_user_and_flaggable(user, flaggable).try(:first) end diff --git a/app/models/moderator.rb b/app/models/moderator.rb index 30d4f4394..6a5af7a52 100644 --- a/app/models/moderator.rb +++ b/app/models/moderator.rb @@ -1,5 +1,5 @@ class Moderator < ActiveRecord::Base - belongs_to :user + belongs_to :user, touch: true delegate :name, :email, to: :user validates :user_id, presence: true, uniqueness: true diff --git a/app/models/organization.rb b/app/models/organization.rb index fa991fc05..2962724a6 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,5 +1,5 @@ class Organization < ActiveRecord::Base - belongs_to :user + belongs_to :user, touch: true validates :name, presence: true diff --git a/app/models/user.rb b/app/models/user.rb index 71db4ee2e..0ae4d3290 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -36,6 +36,17 @@ class User < ActiveRecord::Base scope :officials, -> { where("official_level > 0") } scope :for_render, -> { includes(:organization) } + after_update :touch_debates, :touch_comments + after_touch :touch_debates, :touch_comments + + def touch_debates + debates.map(&:touch) + end + + def touch_comments + comments.map(&:touch) + end + def self.find_for_oauth(auth, signed_in_resource = nil) # Get the identity and user if they exist identity = Identity.find_for_oauth(auth) diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb index 3ee61e9f4..8bf07a8b3 100644 --- a/app/views/comments/_comment.html.erb +++ b/app/views/comments/_comment.html.erb @@ -1,101 +1,104 @@ -
-
+<% cache [locale_and_user_status, comment, @commentable, Flag.flagged?(current_user, comment)] do %> +
+
- <% if comment.hidden? || comment.user.hidden? %> - <% if select_children(@comments, comment).size > 0 %> -
-

<%= t("debates.comment.deleted") %>

-
- <% end %> - <% else %> - <% if comment.as_administrator? %> - <%= image_tag("admin_avatar.png", size: 32, class: "admin-avatar left") %> - <% elsif comment.as_moderator? %> - <%= image_tag("moderator_avatar.png", size: 32, class: "moderator-avatar left") %> + <% if comment.hidden? || comment.user.hidden? %> + <% if select_children(@comments, comment).size > 0 %> +
+

<%= t("debates.comment.deleted") %>

+
+ <% end %> <% else %> - <% if comment.user.organization? %> - <%= image_tag("collective_avatar.png", size: 32, class: "avatar left") %> + <% if comment.as_administrator? %> + <%= image_tag("admin_avatar.png", size: 32, class: "admin-avatar left") %> + <% elsif comment.as_moderator? %> + <%= image_tag("moderator_avatar.png", size: 32, class: "moderator-avatar left") %> <% else %> - <%= avatar_image(comment.user, seed: comment.user_id, size: 32, class: "left") %> - <% end %> - <% if comment.user.hidden? %> - - <% end %> - <% end %> - -
-
- - <% if comment.as_administrator? %> - <%= t("debates.comment.admin") %> #<%= comment.administrator_id%> - <% elsif comment.as_moderator? %> - <%= t("debates.comment.moderator") %> #<%= comment.moderator_id%> + <% if comment.user.organization? %> + <%= image_tag("collective_avatar.png", size: 32, class: "avatar left") %> <% else %> + <%= avatar_image(comment.user, seed: comment.user_id, size: 32, class: "left") %> + <% end %> + <% if comment.user.hidden? %> + + <% end %> + <% end %> - <% if comment.user.hidden? %> - <%= t("debates.comment.user_deleted") %> +
+
+ + <% if comment.as_administrator? %> + <%= t("debates.comment.admin") %> #<%= comment.administrator_id%> + <% elsif comment.as_moderator? %> + <%= t("debates.comment.moderator") %> #<%= comment.moderator_id%> <% else %> - <%= comment.user.name %> - <% if comment.user.official? %> + + <% if comment.user.hidden? %> + <%= t("debates.comment.user_deleted") %> + <% else %> + <%= comment.user.name %> + <% if comment.user.official? %> +  •  + + <%= comment.user.official_position %> + + <% end %> + <% end %> + <% if comment.user.verified_organization? %>  •  - - <%= comment.user.official_position %> + + <%= t("shared.collective") %> <% end %> - <% end %> - <% if comment.user.verified_organization? %> -  •  - - <%= t("shared.collective") %> - - <% end %> - <% if comment.user_id == @commentable.author_id %> -  •  - - <%= t("debates.comment.author") %> - + <% if comment.user_id == @commentable.author_id %> +  •  + + <%= t("debates.comment.author") %> + + <% end %> + <% end %> +  • <%= time_ago_in_words(comment.created_at) %> +
+ + <% if comment.as_administrator? %> +

<%= comment.body %>

+ <% elsif comment.as_moderator? %> +

<%= comment.body %>

+ <% elsif comment.user.official? && comment.user_id == @commentable.author_id %> +

<%= comment.body %>

+ <% elsif comment.user.official? %> +

<%= comment.body %>

+ <% elsif comment.user_id == @commentable.author_id %> +

<%= comment.body %>

+ <% else %> +

<%= comment.body %>

<% end %> + + <%= render 'comments/votes', comment: comment %> + -  • <%= time_ago_in_words(comment.created_at) %> +
+ <%= t("debates.comment.responses", count: select_children(@comments, comment).size) %> + + <% if user_signed_in? %> +  |  + <%= link_to(comment_link_text(comment), "", + class: "js-add-comment-link", data: {'id': dom_id(comment)}) %> + + <%= render 'comments/actions', comment: comment %> + + <%= render 'comments/form', {commentable: @commentable, parent_id: comment.id, toggeable: true} %> + <% end %> +
- - <% if comment.as_administrator? %> -

<%= comment.body %>

- <% elsif comment.as_moderator? %> -

<%= comment.body %>

- <% elsif comment.user.official? && comment.user_id == @commentable.author_id %> -

<%= comment.body %>

- <% elsif comment.user.official? %> -

<%= comment.body %>

- <% elsif comment.user_id == @commentable.author_id %> -

<%= comment.body %>

- <% else %> -

<%= comment.body %>

- <% end %> - - <%= render 'comments/votes', comment: comment %> - - -
- <%= t("debates.comment.responses", count: select_children(@comments, comment).size) %> - - <% if user_signed_in? %> -  |  - <%= link_to(comment_link_text(comment), "", - class: "js-add-comment-link", data: {'id': dom_id(comment)}) %> - - <%= render 'comments/actions', comment: comment %> - - <%= render 'comments/form', {commentable: @commentable, parent_id: comment.id, toggeable: true} %> - <% end %> -
-
- <% end %> - + <% end %> +<% end %>
- <%= render select_children(@comments, comment) if @comments.present? %> + <% select_children(@comments, comment).each do |child| %> + <%= render 'comments/comment', comment: child %> + <% end %>
-
+
\ No newline at end of file diff --git a/app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb index 9a7d26554..eb2507136 100644 --- a/app/views/comments/_form.html.erb +++ b/app/views/comments/_form.html.erb @@ -1,25 +1,28 @@ <% css_id = parent_or_commentable_dom_id(parent_id, commentable) %> -
> - <%= form_for [commentable, Comment.new], remote: true do |f| %> - <%= label_tag "comment-body-#{css_id}", t("comments.form.leave_comment") %> - <%= f.text_area :body, id: "comment-body-#{css_id}", label: false %> - <%= f.hidden_field :commentable_type, value: commentable.class.name %> - <%= f.hidden_field :commentable_id, value: commentable.id %> - <%= f.hidden_field :parent_id, value: parent_id %> +<% cache [locale_and_user_status, css_id] do %> +
> + <%= form_for [commentable, Comment.new], remote: true do |f| %> + <%= label_tag "comment-body-#{css_id}", t("comments.form.leave_comment") %> + <%= f.text_area :body, id: "comment-body-#{css_id}", label: false %> + <%= f.hidden_field :commentable_type, value: commentable.class.name %> + <%= f.hidden_field :commentable_id, value: commentable.id %> + <%= f.hidden_field :parent_id, value: parent_id %> - <%= f.submit comment_button_text(parent_id), class: "button radius small inline-block" %> + <%= f.submit comment_button_text(parent_id), class: "button radius small inline-block" %> + + <% if can? :comment_as_moderator, commentable %>º +
+ <%= f.check_box :as_moderator, id: "comment-as-moderator-#{css_id}", label: false %> + <%= label_tag "comment-as-moderator-#{css_id}", t("comments.form.comment_as_moderator"), class: "checkbox" %> +
+ <% end %> + <% if can? :comment_as_administrator, commentable %> +
+ <%= f.check_box :as_administrator, id: "comment-as-administrator-#{css_id}",label: false %> + <%= label_tag "comment-as-administrator-#{css_id}", t("comments.form.comment_as_admin"), class: "checkbox" %> +
+ <% end %> - <% if can? :comment_as_moderator, commentable %>º -
- <%= f.check_box :as_moderator, id: "comment-as-moderator-#{css_id}", label: false %> - <%= label_tag "comment-as-moderator-#{css_id}", t("comments.form.comment_as_moderator"), class: "checkbox" %> -
<% end %> - <% if can? :comment_as_administrator, commentable %> -
- <%= f.check_box :as_administrator, id: "comment-as-administrator-#{css_id}",label: false %> - <%= label_tag "comment-as-administrator-#{css_id}", t("comments.form.comment_as_admin"), class: "checkbox" %> -
- <% end %> - <% end %> -
+
+<% end %> \ No newline at end of file diff --git a/app/views/debates/_comments.html.erb b/app/views/debates/_comments.html.erb new file mode 100644 index 000000000..39ed635ba --- /dev/null +++ b/app/views/debates/_comments.html.erb @@ -0,0 +1,30 @@ +<% cache [locale_and_user_status, @all_visible_comments.map(&:cache_key), @debate.comments_count, @comment_flags.to_a] do %> +
+
+
+ +

+ <%= t("debates.show.comments_title") %> + (<%= @debate.comments_count %>) +

+ + <% if user_signed_in? %> + <%= render 'comments/form', {commentable: @debate, parent_id: nil, toggeable: false} %> + <% else %> +
+ +
+ <%= t("debates.show.login_to_comment", + signin: link_to(t("votes.signin"), new_user_session_path), + signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %> +
+ <% end %> + + <% @root_comments.each do |comment| %> + <%= render 'comments/comment', comment: comment %> + <% end %> + <%= paginate @root_comments %> +
+
+
+<% end %> \ No newline at end of file diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb index 3ed8b3a9d..1767266db 100644 --- a/app/views/debates/show.html.erb +++ b/app/views/debates/show.html.erb @@ -1,99 +1,81 @@ -
-
-
-  <%= link_to t("debates.show.back_link"), debates_path, class: 'left back' %> +<% cache [locale_and_user_status, @debate, Flag.flagged?(current_user, @debate)] do %> +
+
+
+   + <%= link_to t("debates.show.back_link"), debates_path, class: 'left back' %> - <% if current_user && @debate.editable_by?(current_user) %> - <%= link_to edit_debate_path(@debate), :class => 'edit-debate button success tiny radius right' do %> - - <%= t("debates.show.edit_debate_link") %> - <% end %> - <% end %> - -

<%= @debate.title %>

- -
- <%= avatar_image(@debate.author, seed: @debate.author_id, size: 32, class: 'author-photo') %> - <% if @debate.author.hidden? %> - - - <%= t("debates.show.author_deleted") %> - - <% else %> - - <%= @debate.author.name %> - - <% if @debate.author.official? %> -  •  - - <%= @debate.author.official_position %> - + <% if current_user && @debate.editable_by?(current_user) %> + <%= link_to edit_debate_path(@debate), class: 'edit-debate button success tiny radius right' do %> + + <%= t("debates.show.edit_debate_link") %> <% end %> <% end %> - <% if @debate.author.verified_organization? %> -  •  - - <%= t("shared.collective") %> + +

<%= @debate.title %>

+ +
+ <%= avatar_image(@debate.author, seed: @debate.author_id, size: 32, class: 'author-photo') %> + + <% if @debate.author.hidden? %> + + + <%= t("debates.show.author_deleted") %> + + <% else %> + + <%= @debate.author.name %> + + <% if @debate.author.official? %> +  •  + + <%= @debate.author.official_position %> + + <% end %> + <% end %> + + <% if @debate.author.verified_organization? %> +  •  + + <%= t("shared.collective") %> + + <% end %> + +  •  + <%= l @debate.created_at.to_date %> +  •  +   + <%= link_to t("debates.show.comments", count: @debate.comments_count), "#comments" %> +  •  + + <%= render 'debates/flag_actions', debate: @debate %> +
+ + <%= @debate.description %> + + <%= render 'shared/tags', debate: @debate %> + + <% if moderator? %> +
+ <%= render 'actions', debate: @debate %> +
<% end %> -  •  - <%= l @debate.created_at.to_date %> -  •  -   - <%= link_to t("debates.show.comments", count: @debate.comments_count), "#comments" %> -  •  - - <%= render 'debates/flag_actions', debate: @debate %> -
- <%= @debate.description %> - - <%= render 'shared/tags', debate: @debate %> - - <% if moderator? %> -
- <%= render 'actions', debate: @debate %> +
- - -
-
- -
-
-
- -

- <%= t("debates.show.comments_title") %> - (<%= @debate.comments_count %>) -

- <% if user_signed_in? %> - <%= render 'comments/form', {commentable: @debate, parent_id: nil, toggeable: false} %> - <% else %> -
-
- <%= t("debates.show.login_to_comment", - signin: link_to(t("votes.signin"), new_user_session_path), - signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %> -
- <% end %> - - <%= render @root_comments %> - <%= paginate @root_comments %> -
-
-
+
+<% end %> +<%= render "comments" %> \ No newline at end of file diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index 490a5cfd1..8798f4935 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -36,4 +36,34 @@ describe Comment do expect(comment).to be_as_moderator end end + + describe "cache" do + let(:comment) { create(:comment) } + + it "should expire cache when it has a new vote" do + expect { create(:vote, votable: comment) } + .to change { comment.updated_at } + end + + it "should expire cache when hidden" do + expect { comment.hide } + .to change { comment.updated_at } + end + + it "should expire cache when the author is hidden" do + expect { comment.user.hide } + .to change { comment.reload.updated_at } + end + + it "should expire cache when the author changes" do + expect { comment.user.update(username: "Isabel") } + .to change { comment.reload.updated_at } + end + + it "should expire cache when the author's organization get verified" do + create(:organization, user: comment.user) + expect { comment.user.organization.verify } + .to change { comment.reload.updated_at} + end + end end diff --git a/spec/models/debate_spec.rb b/spec/models/debate_spec.rb index 25e878d18..951837956 100644 --- a/spec/models/debate_spec.rb +++ b/spec/models/debate_spec.rb @@ -268,4 +268,34 @@ describe Debate do end end + describe "cache" do + let(:debate) { create(:debate) } + + it "should expire cache when it has a new comment" do + expect { create(:comment, commentable: debate) } + .to change { debate.updated_at } + end + + it "should expire cache when it has a new vote" do + expect { create(:vote, votable: debate) } + .to change { debate.updated_at } + end + + it "should expire cache when it has a new tag" do + expect { debate.update(tag_list: "new tag") } + .to change { debate.updated_at } + end + + it "should expire cache when its author changes" do + expect { debate.author.update(username: "Eva") } + .to change { debate.reload.updated_at } + end + + it "should expire cache when the author's organization get verified" do + create(:organization, user: debate.author) + expect { debate.author.organization.verify } + .to change { debate.reload.updated_at} + end + end + end \ No newline at end of file diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 282d8d615..f9c24ec4d 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -299,4 +299,25 @@ describe User do end end + describe "cache" do + let(:user) { create(:user) } + + it "should expire cache with becoming a moderator" do + expect { create(:moderator, user: user) } + .to change { user.updated_at} + end + + it "should expire cache with becoming an admin" do + expect { create(:administrator, user: user) } + .to change { user.updated_at} + end + + it "should expire cache with becoming a veridied organization" do + create(:organization, user: user) + expect { user.organization.verify } + .to change { user.reload.updated_at} + end + + end + end