From c82e891c03351dd8b23b7adaf103286d8b4a4efd Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Thu, 21 Sep 2017 01:35:18 +0200 Subject: [PATCH] Add reference source and target behaviour --- app/models/comment.rb | 1 + app/models/message.rb | 2 ++ app/models/reference.rb | 16 ++++++++++++++ app/models/status_message.rb | 3 +++ spec/models/comment_spec.rb | 1 + spec/models/message_spec.rb | 2 ++ spec/models/status_message_spec.rb | 3 +++ spec/shared_behaviors/references.rb | 33 +++++++++++++++++++++++++++++ 8 files changed, 61 insertions(+) create mode 100644 spec/shared_behaviors/references.rb diff --git a/app/models/comment.rb b/app/models/comment.rb index e165b09ff..a766566fc 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -14,6 +14,7 @@ class Comment < ApplicationRecord include Diaspora::Taggable include Diaspora::Likeable include Diaspora::MentionsContainer + include Reference::Source acts_as_taggable_on :tags extract_tags_from :text diff --git a/app/models/message.rb b/app/models/message.rb index 7e1857fe9..e0c738d00 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -5,6 +5,8 @@ class Message < ApplicationRecord include Diaspora::Fields::Guid include Diaspora::Fields::Author + include Reference::Source + belongs_to :conversation, touch: true delegate :name, to: :author, prefix: true diff --git a/app/models/reference.rb b/app/models/reference.rb index 926915a7c..87a04ed2a 100644 --- a/app/models/reference.rb +++ b/app/models/reference.rb @@ -4,4 +4,20 @@ class Reference < ApplicationRecord belongs_to :source, polymorphic: true belongs_to :target, polymorphic: true validates :target_id, uniqueness: {scope: %i[target_type source_id source_type]} + + module Source + extend ActiveSupport::Concern + + included do + has_many :references, as: :source, dependent: :destroy + end + end + + module Target + extend ActiveSupport::Concern + + included do + has_many :referenced_by, as: :target, class_name: "Reference", dependent: :destroy + end + end end diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 43ae1697d..a44afca90 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -7,6 +7,9 @@ class StatusMessage < Post include Diaspora::Taggable + include Reference::Source + include Reference::Target + include PeopleHelper acts_as_taggable_on :tags diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index 8e84dca2f..9b426b224 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -10,6 +10,7 @@ describe Comment, type: :model do let(:comment_alice) { alice.comment!(status_bob, "why so formal?") } it_behaves_like "it is mentions container" + it_behaves_like "a reference source" describe "#destroy" do it "should delete a participation" do diff --git a/spec/models/message_spec.rb b/spec/models/message_spec.rb index 6127c008f..031df4a9a 100644 --- a/spec/models/message_spec.rb +++ b/spec/models/message_spec.rb @@ -52,4 +52,6 @@ describe Message, type: :model do expect(conf.reload.unread).to eq(1) end end + + it_behaves_like "a reference source" end diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index 8c1165a21..8dfca6f67 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -147,6 +147,9 @@ describe StatusMessage, type: :model do end end + it_behaves_like "a reference source" + it_behaves_like "a reference target" + describe "#nsfw" do it "returns MatchObject (true) if the post contains #nsfw (however capitalised)" do status = FactoryGirl.build(:status_message, text: "This message is #nSFw") diff --git a/spec/shared_behaviors/references.rb b/spec/shared_behaviors/references.rb new file mode 100644 index 000000000..d78829baf --- /dev/null +++ b/spec/shared_behaviors/references.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +shared_examples_for "a reference source" do + let!(:source) { FactoryGirl.create(described_class.to_s.underscore.to_sym) } + let!(:reference) { FactoryGirl.create(:reference, source: source) } + + describe "references" do + it "returns the references" do + expect(source.references).to match_array([reference]) + end + + it "destroys the reference when the source is destroyed" do + source.destroy + expect(Reference.where(id: reference.id)).not_to exist + end + end +end + +shared_examples_for "a reference target" do + let!(:target) { FactoryGirl.create(described_class.to_s.underscore.to_sym) } + let!(:reference) { FactoryGirl.create(:reference, target: target) } + + describe "referenced_by" do + it "returns the references where the target is referenced" do + expect(target.referenced_by).to match_array([reference]) + end + + it "destroys the reference when the target is destroyed" do + target.destroy + expect(Reference.where(id: reference.id)).not_to exist + end + end +end