diff --git a/app/controllers/related_contents_controller.rb b/app/controllers/related_contents_controller.rb
new file mode 100644
index 000000000..06bfaadc7
--- /dev/null
+++ b/app/controllers/related_contents_controller.rb
@@ -0,0 +1,42 @@
+class RelatedContentsController < ApplicationController
+ VALID_URL = /#{Setting['url']}\/.*\/.*/
+
+ skip_authorization_check
+
+ def create
+ if relationable_object && related_object
+ @relationable.relate_content(@related)
+
+ flash[:success] = t('related_content.success')
+ else
+ flash[:error] = t('related_content.error', url: Setting['url'])
+ end
+
+ redirect_to @relationable
+ end
+
+ private
+
+ def valid_url?
+ params[:url].match(VALID_URL)
+ end
+
+ def relationable_object
+ @relationable = (params[:relationable_klass].singularize.camelize.constantize).find_by_id(params[:relationable_id])
+ end
+
+ def related_object
+ begin
+ if valid_url?
+ url = params[:url]
+
+ related_klass = url.match(/\/(#{RelatedContent::RELATIONABLE_MODELS.join("|")})\//)[0].gsub("/", "")
+ related_id = url.match(/\/[0-9]+/)[0].gsub("/", "")
+
+ @related = (related_klass.singularize.camelize.constantize).find_by_id(related_id)
+ end
+ rescue
+ nil
+ end
+ end
+end
diff --git a/app/models/related_content.rb b/app/models/related_content.rb
index ab72aefe3..fa41a57ad 100644
--- a/app/models/related_content.rb
+++ b/app/models/related_content.rb
@@ -1,5 +1,6 @@
class RelatedContent < ActiveRecord::Base
RELATED_CONTENTS_REPORT_THRESHOLD = Setting['related_contents_report_threshold'].to_i
+ RELATIONABLE_MODELS = %w{proposals debates}
belongs_to :parent_relationable, polymorphic: true
belongs_to :child_relationable, polymorphic: true
diff --git a/app/views/relationable/_form.html.erb b/app/views/relationable/_form.html.erb
new file mode 100644
index 000000000..930c839a2
--- /dev/null
+++ b/app/views/relationable/_form.html.erb
@@ -0,0 +1,22 @@
+<%= form_tag related_contents_path, method: :post, id: "related_content", class: "hide", "data-toggler": ".hide" do %>
+
+
+
+ <%= t("related_content.help", models: t('related_content.content_title').values.to_sentence, org: setting['org_name']) %>
+
+
+
+ <% end %>
diff --git a/app/views/relationable/_related_content.html.erb b/app/views/relationable/_related_content.html.erb
index e780d3cf7..19435fec2 100644
--- a/app/views/relationable/_related_content.html.erb
+++ b/app/views/relationable/_related_content.html.erb
@@ -4,12 +4,15 @@
<%= t("related_content.title") %> (<%= relationable.relationed_contents.count %>)
-
-
- <%= t("related_content.add") %>
+
+
+ <%= render 'relationable/form', relationable: relationable %>
+
<%= render 'relationable/related_list', relationable: relationable %>
diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml
index aad6031a8..3391bc3fd 100644
--- a/config/locales/en/general.yml
+++ b/config/locales/en/general.yml
@@ -817,7 +817,7 @@ en:
add: "Add related content"
label: "Link to related content"
placeholder: "%{url}"
- help: "You can add any link inside of %{org}."
+ help: "You can add links of %{models} inside of %{org}."
submit: "Add"
error: "Link not valid. Remember to start with %{url}."
success: "You added a new related content"
diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml
index 15a29856f..db290316c 100644
--- a/config/locales/es/general.yml
+++ b/config/locales/es/general.yml
@@ -814,7 +814,7 @@ es:
add: "Añadir contenido relacionado"
label: "Enlace a contenido relacionado"
placeholder: "%{url}"
- help: "Puedes introducir cualquier enlace que esté dentro de %{org}."
+ help: "Puedes introducir cualquier enlace de %{models} que esté dentro de %{org}."
submit: "Añadir"
error: "Enlace no válido. Recuerda que debe empezar por %{url}."
success: "Has añadido un nuevo contenido relacionado"
diff --git a/config/routes.rb b/config/routes.rb
index 31d811293..429e5a862 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -462,6 +462,8 @@ Rails.application.routes.draw do
root to: "dashboard#index"
end
+ resources :related_contents, only: [:create]
+
# GraphQL
get '/graphql', to: 'graphql#query'
post '/graphql', to: 'graphql#query'
diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb
index e9c5dbd6d..9f64abd40 100644
--- a/spec/features/proposals_spec.rb
+++ b/spec/features/proposals_spec.rb
@@ -139,6 +139,57 @@ feature 'Proposals' do
expect(page).to have_content(proposal1.title)
end
end
+
+ scenario 'related contents can be added' do
+ proposal1 = create(:proposal)
+ proposal2 = create(:proposal)
+ debate1 = create(:debate)
+
+ visit proposal_path(proposal1)
+
+ expect(page).to have_selector('#related_content', visible: false)
+ click_on("Add related content")
+ expect(page).to have_selector('#related_content', visible: true)
+
+ within("#related_content") do
+ fill_in 'url', with: "#{Setting['url']}/proposals/#{proposal2.to_param}"
+ click_button "Add"
+ end
+
+ within("#related-content-list") do
+ expect(page).to have_content(proposal2.title)
+ end
+
+ visit proposal_path(proposal2)
+
+ within("#related-content-list") do
+ expect(page).to have_content(proposal1.title)
+ end
+
+ within("#related_content") do
+ fill_in 'url', with: "#{Setting['url']}/debates/#{debate1.to_param}"
+ click_button "Add"
+ end
+
+ within("#related-content-list") do
+ expect(page).to have_content(debate1.title)
+ end
+ end
+
+ scenario 'if related content URL is invalid returns error' do
+ proposal1 = create(:proposal)
+
+ visit proposal_path(proposal1)
+
+ click_on("Add related content")
+
+ within("#related_content") do
+ fill_in 'url', with: "http://invalidurl.com"
+ click_button "Add"
+ end
+
+ expect(page).to have_content("Link not valid. Remember to start with #{Setting[:url]}.")
+ end
end
context "Embedded video" do