diff --git a/app/controllers/related_contents_controller.rb b/app/controllers/related_contents_controller.rb index e6ebac6b0..2acc18cff 100644 --- a/app/controllers/related_contents_controller.rb +++ b/app/controllers/related_contents_controller.rb @@ -4,10 +4,10 @@ class RelatedContentsController < ApplicationController respond_to :html, :js def create - related_content = RelatedContent.new( - parent_relationable: relationable_object, - child_relationable: related_object, - author: current_user + related_content = current_user.related_contents.new( + parent_relationable_id: params[:relationable_id], + parent_relationable_type: params[:relationable_klass], + child_relationable: related_object ) if related_content.save @@ -17,7 +17,7 @@ class RelatedContentsController < ApplicationController else flash[:error] = t("related_content.error", url: Setting["url"]) end - redirect_to polymorphic_path(relationable_object) + redirect_to polymorphic_path(related_content.parent_relationable) end def score_positive @@ -41,10 +41,6 @@ class RelatedContentsController < ApplicationController params[:url].start_with?(Setting["url"]) end - def relationable_object - @relationable ||= params[:relationable_klass].singularize.camelize.constantize.find_by(id: params[:relationable_id]) - end - def related_object if valid_url? url = params[:url] diff --git a/app/models/related_content.rb b/app/models/related_content.rb index c383bf376..3b9074d32 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -6,15 +6,11 @@ class RelatedContent < ApplicationRecord include ActsAsParanoidAliases belongs_to :author, class_name: "User" - belongs_to :parent_relationable, polymorphic: true, touch: true - belongs_to :child_relationable, polymorphic: true, touch: true + belongs_to :parent_relationable, polymorphic: true, optional: false, touch: true + belongs_to :child_relationable, polymorphic: true, optional: false, touch: true has_one :opposite_related_content, class_name: self.name, foreign_key: :related_content_id has_many :related_content_scores - validates :parent_relationable_id, presence: true - validates :parent_relationable_type, presence: true - 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 diff --git a/app/models/user.rb b/app/models/user.rb index e6304a318..75da22c3b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -74,6 +74,7 @@ class User < ApplicationRecord class_name: "Poll::Recount", foreign_key: :author_id, inverse_of: :author + has_many :related_contents, foreign_key: :author_id, inverse_of: :author, dependent: nil has_many :topics, foreign_key: :author_id, inverse_of: :author belongs_to :geozone diff --git a/spec/models/related_content_spec.rb b/spec/models/related_content_spec.rb index 75d540624..86bef5d23 100644 --- a/spec/models/related_content_spec.rb +++ b/spec/models/related_content_spec.rb @@ -3,9 +3,10 @@ require "rails_helper" describe RelatedContent do let(:parent_relationable) { create([:proposal, :debate].sample) } let(:child_relationable) { create([:proposal, :debate].sample) } + let(:related_content) { build(:related_content) } it "is valid" do - expect(build(:related_content)).to be_valid + expect(related_content).to be_valid end it "allows relationables from various classes" do @@ -33,6 +34,28 @@ describe RelatedContent do expect(related_content).not_to be_valid end + it "is not valid with an invalid parent relationable type" do + related_content.parent_relationable_type = "NotARealModel" + + expect { related_content.valid? }.to raise_exception "uninitialized constant NotARealModel" + end + + it "is not valid with parent relationable ID of a non-existent record" do + related_content.parent_relationable_id = related_content.parent_relationable.class.last.id + 1 + + expect(related_content).not_to be_valid + end + + it "is not valid with an invalid child relationable type" do + related_content.child_relationable_type = "NotARealModel" + + expect { related_content.valid? }.to raise_exception "uninitialized constant NotARealModel" + end + + it "is not valid with child relationable ID of a non-existent record" do + related_content.child_relationable_id = related_content.child_relationable.class.last.id + 1 + end + describe "create_opposite_related_content" do let(:parent_relationable) { create(:proposal) } let(:child_relationable) { create(:debate) }