diff --git a/app/controllers/related_contents_controller.rb b/app/controllers/related_contents_controller.rb index bbb391465..e6ebac6b0 100644 --- a/app/controllers/related_contents_controller.rb +++ b/app/controllers/related_contents_controller.rb @@ -4,18 +4,20 @@ class RelatedContentsController < ApplicationController respond_to :html, :js def create - if relationable_object && related_object - if relationable_object != related_object - RelatedContent.create!(parent_relationable: @relationable, child_relationable: @related, author: current_user) + related_content = RelatedContent.new( + parent_relationable: relationable_object, + child_relationable: related_object, + author: current_user + ) - flash[:success] = t("related_content.success") - else - flash[:error] = t("related_content.error_itself") - end + if related_content.save + flash[:success] = t("related_content.success") + elsif related_content.same_parent_and_child? + flash[:error] = t("related_content.error_itself") else flash[:error] = t("related_content.error", url: Setting["url"]) end - redirect_to polymorphic_path(@relationable) + redirect_to polymorphic_path(relationable_object) end def score_positive @@ -40,7 +42,7 @@ class RelatedContentsController < ApplicationController end def relationable_object - @relationable = params[:relationable_klass].singularize.camelize.constantize.find_by(id: params[:relationable_id]) + @relationable ||= params[:relationable_klass].singularize.camelize.constantize.find_by(id: params[:relationable_id]) end def related_object @@ -51,7 +53,7 @@ class RelatedContentsController < ApplicationController .flatten.map { |i| i.to_s.singularize.camelize }.join("::") related_id = url.match(/\/(\d+)(?!.*\/\d)/)[1] - @related = related_klass.singularize.camelize.constantize.find_by(id: related_id) + related_klass.singularize.camelize.constantize.find_by(id: related_id) end rescue nil diff --git a/app/models/related_content.rb b/app/models/related_content.rb index 8a81413ed..c383bf376 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -16,6 +16,7 @@ class RelatedContent < ApplicationRecord validates :child_relationable_id, presence: true validates :child_relationable_type, presence: true validates :parent_relationable_id, uniqueness: { scope: [:parent_relationable_type, :child_relationable_id, :child_relationable_type] } + validate :different_parent_and_child after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? } after_create :create_author_score @@ -34,8 +35,18 @@ class RelatedContent < ApplicationRecord related_content_scores.exists?(user: user) end + def same_parent_and_child? + parent_relationable == child_relationable + end + private + def different_parent_and_child + if same_parent_and_child? + errors.add(:parent_relationable, :itself) + end + end + def create_opposite_related_content related_content = RelatedContent.create!(opposite_related_content: self, parent_relationable: child_relationable, child_relationable: parent_relationable, author: author) diff --git a/spec/models/related_content_spec.rb b/spec/models/related_content_spec.rb index 557ff3e53..75d540624 100644 --- a/spec/models/related_content_spec.rb +++ b/spec/models/related_content_spec.rb @@ -25,6 +25,14 @@ describe RelatedContent do expect(new_related_content).not_to be_valid end + it "does not allow relating a content to itself" do + related_content = build(:related_content, + parent_relationable: parent_relationable, + child_relationable: parent_relationable) + + expect(related_content).not_to be_valid + end + describe "create_opposite_related_content" do let(:parent_relationable) { create(:proposal) } let(:child_relationable) { create(:debate) }