diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss
index b49c5d17d..62e09e088 100644
--- a/app/assets/stylesheets/layout.scss
+++ b/app/assets/stylesheets/layout.scss
@@ -2436,7 +2436,7 @@ table {
font-weight: normal;
}
- span {
+ span:not(.icon-flag) {
color: #4f4f4f;
font-size: rem-calc(12);
text-transform: uppercase;
@@ -2452,4 +2452,4 @@ table {
.images .button {
margin-top: $line-height / 2;
-}
\ No newline at end of file
+}
diff --git a/app/controllers/related_contents_controller.rb b/app/controllers/related_contents_controller.rb
index 1ea9e02f9..8e2cd854d 100644
--- a/app/controllers/related_contents_controller.rb
+++ b/app/controllers/related_contents_controller.rb
@@ -3,6 +3,8 @@ class RelatedContentsController < ApplicationController
skip_authorization_check
+ respond_to :html, :js
+
def create
if relationable_object && related_object
@relationable.relate_content(@related)
@@ -15,6 +17,24 @@ class RelatedContentsController < ApplicationController
redirect_to @relationable
end
+ def flag
+ @related = RelatedContent.find_by(id: params[:id])
+
+ Flag.flag(current_user, @related)
+ Flag.flag(current_user, @related.opposite_related_content)
+
+ render template: 'relationable/_refresh_flag_actions'
+ end
+
+ def unflag
+ @related = RelatedContent.find_by(id: params[:id])
+
+ Flag.unflag(current_user, @related)
+ Flag.unflag(current_user, @related.opposite_related_content)
+
+ render template: 'relationable/_refresh_flag_actions'
+ end
+
private
def valid_url?
diff --git a/app/helpers/flags_helper.rb b/app/helpers/flags_helper.rb
index 9983b34ae..44da7938d 100644
--- a/app/helpers/flags_helper.rb
+++ b/app/helpers/flags_helper.rb
@@ -21,6 +21,8 @@ module FlagsHelper
def own_flaggable?(flaggable)
if flaggable.is_a? Comment
flaggable.user_id == current_user.id
+ elsif flaggable.is_a? RelatedContent
+ false
else
flaggable.author_id == current_user.id
end
diff --git a/app/models/concerns/relationable.rb b/app/models/concerns/relationable.rb
index 26f755f03..4ef03990e 100644
--- a/app/models/concerns/relationable.rb
+++ b/app/models/concerns/relationable.rb
@@ -16,8 +16,8 @@ module Relationable
def report_related_content(relationable)
related_content = related_contents.find_by(child_relationable: relationable)
if related_content.present?
- related_content.increment!(:times_reported)
- related_content.opposite_related_content.increment!(:times_reported)
+ related_content.increment!(:flags_count)
+ related_content.opposite_related_content.increment!(:flags_count)
end
end
end
diff --git a/app/models/related_content.rb b/app/models/related_content.rb
index 4fbb1f48d..7c9515035 100644
--- a/app/models/related_content.rb
+++ b/app/models/related_content.rb
@@ -1,9 +1,11 @@
class RelatedContent < ActiveRecord::Base
+ include Flaggable
+
RELATED_CONTENTS_REPORT_THRESHOLD = Setting['related_contents_report_threshold'].to_i
RELATIONABLE_MODELS = %w{proposals debates}.freeze
- belongs_to :parent_relationable, polymorphic: true
- belongs_to :child_relationable, polymorphic: true
+ belongs_to :parent_relationable, polymorphic: true, touch: true
+ belongs_to :child_relationable, polymorphic: true, touch: true
has_one :opposite_related_content, class_name: 'RelatedContent', foreign_key: :related_content_id
validates :parent_relationable_id, presence: true
@@ -15,10 +17,10 @@ class RelatedContent < ActiveRecord::Base
after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? }
after_destroy :destroy_opposite_related_content, if: proc { opposite_related_content.present? }
- scope :not_hidden, -> { where('times_reported <= ?', RELATED_CONTENTS_REPORT_THRESHOLD) }
+ scope :not_hidden, -> { where('flags_count <= ?', RELATED_CONTENTS_REPORT_THRESHOLD) }
def hidden_by_reports?
- times_reported > RELATED_CONTENTS_REPORT_THRESHOLD
+ flags_count > RELATED_CONTENTS_REPORT_THRESHOLD
end
private
diff --git a/app/views/relationable/_flag_actions.html.erb b/app/views/relationable/_flag_actions.html.erb
new file mode 100644
index 000000000..d501b098d
--- /dev/null
+++ b/app/views/relationable/_flag_actions.html.erb
@@ -0,0 +1,19 @@
+
+ <% if show_flag_action? related %>
+
+
+
+
+ <%= link_to t('shared.flag'), flag_related_content_path(related), method: :put, remote: true, id: "flag-related-#{ related.id }" %>
+
+ <% end %>
+
+ <% if show_unflag_action? related %>
+
+
+
+
+ <%= link_to t('shared.unflag'), unflag_related_content_path(related), method: :put, remote: true, id: "unflag-related-#{ related.id }" %>
+
+ <% end %>
+
diff --git a/app/views/relationable/_refresh_flag_actions.js.erb b/app/views/relationable/_refresh_flag_actions.js.erb
new file mode 100644
index 000000000..d3755c4b1
--- /dev/null
+++ b/app/views/relationable/_refresh_flag_actions.js.erb
@@ -0,0 +1 @@
+$("#<%= dom_id(@related) %>.js-flag-actions").html('<%= j render("relationable/flag_actions", related: @related) %>');
diff --git a/app/views/relationable/_related_list.html.erb b/app/views/relationable/_related_list.html.erb
index 08fc931df..f1d86b748 100644
--- a/app/views/relationable/_related_list.html.erb
+++ b/app/views/relationable/_related_list.html.erb
@@ -1,9 +1,9 @@
<% @related_contents.each do |related| %>
-
-
-
-
+
+ <%= render 'relationable/flag_actions', related: related.relate_content(relationable) %>
+
<%= t("related_content.content_title.#{related.class.name.downcase}") %>
diff --git a/config/routes.rb b/config/routes.rb
index 429e5a862..40eb2e139 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -462,7 +462,12 @@ Rails.application.routes.draw do
root to: "dashboard#index"
end
- resources :related_contents, only: [:create]
+ resources :related_contents, only: [:create] do
+ member do
+ put :flag
+ put :unflag
+ end
+ end
# GraphQL
get '/graphql', to: 'graphql#query'
diff --git a/db/migrate/20171215152244_change_related_content_times_reported_column.rb b/db/migrate/20171215152244_change_related_content_times_reported_column.rb
new file mode 100644
index 000000000..7da58bba5
--- /dev/null
+++ b/db/migrate/20171215152244_change_related_content_times_reported_column.rb
@@ -0,0 +1,5 @@
+class ChangeRelatedContentTimesReportedColumn < ActiveRecord::Migration
+ def change
+ rename_column :related_contents, :times_reported, :flags_count
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index c3e107aae..609f59c0f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20171212193323) do
+ActiveRecord::Schema.define(version: 20171215152244) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -862,7 +862,7 @@ ActiveRecord::Schema.define(version: 20171212193323) do
t.integer "related_content_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "times_reported", default: 0
+ t.integer "flags_count", default: 0
end
add_index "related_contents", ["child_relationable_type", "child_relationable_id"], name: "index_related_contents_on_child_relationable", using: :btree
diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb
index 51fdc3f79..baf788c93 100644
--- a/spec/features/proposals_spec.rb
+++ b/spec/features/proposals_spec.rb
@@ -216,6 +216,46 @@ feature 'Proposals' do
expect(page).to have_content("Link not valid. Remember to start with #{Setting[:url]}.")
end
+
+ scenario 'related content can be flagged', :js do
+ user = create(:user)
+ proposal1 = create(:proposal)
+ proposal2 = create(:proposal)
+ related_content = create(:related_content, parent_relationable: proposal1, child_relationable: proposal2)
+
+ login_as(user)
+ visit proposal_path(proposal1)
+
+ within("#related-content-list") do
+ expect(page).to have_css("#flag-expand-related-2")
+ find('#flag-expand-related-2').click
+ expect(page).to have_css("#flag-drop-related-2", visible: true)
+ click_link("flag-related-2")
+
+ expect(page).to have_css("#unflag-expand-related-2")
+ end
+
+ expect(related_content.reload.flags_count).to eq(1)
+ expect(related_content.opposite_related_content.flags_count).to eq(1)
+ end
+
+ scenario 'if related content has been flagged more than 5 times it will be hidden', :js do
+ user = create(:user)
+ proposal1 = create(:proposal)
+ proposal2 = create(:proposal)
+ related_content = create(:related_content, parent_relationable: proposal1, child_relationable: proposal2)
+
+ related_content.flags_count = Setting['related_contents_report_threshold'].to_i + 1
+ related_content.opposite_related_content.flags_count = related_content.flags_count
+
+ related_content.save
+ related_content.opposite_related_content.save
+
+ login_as(user)
+ visit proposal_path(proposal1)
+
+ expect(page).to_not have_css("#related-content-list")
+ end
end
context "Embedded video" do
diff --git a/spec/models/relation_spec.rb b/spec/models/relation_spec.rb
index 86bbe2c14..c2411a158 100644
--- a/spec/models/relation_spec.rb
+++ b/spec/models/relation_spec.rb
@@ -51,18 +51,18 @@ describe RelatedContent do
# TODO: Move this into a Relationable shared context
describe '#report_related_content' do
- it 'increments both relation and opposite relation times_reported counters' do
+ it 'increments both relation and opposite relation flags_count counters' do
related_content = create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)
parent_relationable.report_related_content(child_relationable)
- expect(related_content.reload.times_reported).to eq(1)
- expect(related_content.reload.opposite_related_content.times_reported).to eq(1)
+ expect(related_content.reload.flags_count).to eq(1)
+ expect(related_content.reload.opposite_related_content.flags_count).to eq(1)
end
end
describe '#relationed_contents' do
before do
- create(:related_content, parent_relationable: parent_relationable, child_relationable: create(:proposal), times_reported: 6)
+ create(:related_content, parent_relationable: parent_relationable, child_relationable: create(:proposal), flags_count: 6)
create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)
end