diff --git a/lib/pact_broker/domain/tag.rb b/lib/pact_broker/domain/tag.rb index 85dbafb14..e4d087566 100644 --- a/lib/pact_broker/domain/tag.rb +++ b/lib/pact_broker/domain/tag.rb @@ -2,27 +2,59 @@ require 'pact_broker/repositories/helpers' module PactBroker - module Domain class Tag < Sequel::Model + plugin :timestamps, update_on_create: true + plugin :insert_ignore, identifying_columns: [:name, :version_id] + + unrestrict_primary_key + associate(:many_to_one, :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id) dataset_module do include PactBroker::Repositories::Helpers - end - plugin :insert_ignore, identifying_columns: [:name, :version_id] + def head_tags_for_consumer_id(consumer_id) + lp = :latest_pact_publication_ids_for_consumer_versions + tags_versions_join = { + Sequel[:tags][:version_id] => Sequel[:versions][:id], + Sequel[:versions][:pacticipant_id] => consumer_id + } - unrestrict_primary_key + versions_pact_publications_join = { + Sequel[:versions][:id] => Sequel[lp][:consumer_version_id], + Sequel[lp][:consumer_id] => consumer_id + } + # head tags for this consumer + # the latest tag, pacticipant_id, version order + # for versions that have a pact publication + PactBroker::Domain::Tag + .select_group(Sequel[:tags][:name], Sequel[:versions][:pacticipant_id]) + .select_append{ max(order).as(latest_consumer_version_order) } + .join(:versions, tags_versions_join) + .join(lp, versions_pact_publications_join) + end - associate(:many_to_one, :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id) + def head_tags_for_pact_publication(pact_publication) + head_tags_versions_join = { + Sequel[:head_tags][:latest_consumer_version_order] => Sequel[:versions][:order], + Sequel[:head_tags][:pacticipant_id] => Sequel[:versions][:pacticipant_id], + Sequel[:versions][:pacticipant_id] => pact_publication.consumer_id + } + + # Find the head tags that belong to this pact publication + # Note: The tag model has the name and version_id, + # but does not have the created_at value set - but don't need it for now + head_tags_for_consumer_id(pact_publication.consumer_id).from_self(alias: :head_tags) + .select(Sequel[:head_tags][:name], Sequel[:versions][:id].as(:version_id)) + .join(:versions, head_tags_versions_join) + .where(Sequel[:versions][:id] => pact_publication.consumer_version_id) + end + end def <=> other name <=> other.name end - end - - Tag.plugin :timestamps, :update_on_create=>true end end diff --git a/lib/pact_broker/pacts/all_pact_publications.rb b/lib/pact_broker/pacts/all_pact_publications.rb index 5408cdc34..3768be4d0 100644 --- a/lib/pact_broker/pacts/all_pact_publications.rb +++ b/lib/pact_broker/pacts/all_pact_publications.rb @@ -112,9 +112,7 @@ def to_domain_without_tags end def head_tag_names - # Avoid circular dependency - require 'pact_broker/pacts/latest_tagged_pact_publications' - @head_tag_names ||= LatestTaggedPactPublications.where(id: id).select(:tag_name).collect{|t| t[:tag_name]} + @head_tag_names ||= PactBroker::Domain::Tag.head_tags_for_pact_publication(self).collect(&:name) end def to_domain_with_content diff --git a/lib/pact_broker/pacts/pact_publication.rb b/lib/pact_broker/pacts/pact_publication.rb index 1f25206f0..acc1f6aa9 100644 --- a/lib/pact_broker/pacts/pact_publication.rb +++ b/lib/pact_broker/pacts/pact_publication.rb @@ -111,7 +111,7 @@ def before_create # The names of the tags for which this pact is the latest pact with that tag # (ie. it is not necessarily the pact for the latest consumer version with the given tag) def head_tag_names - LatestTaggedPactPublications.where(id: id).select(:tag_name).collect{|t| t[:tag_name]} + @head_tag_names ||= PactBroker::Domain::Tag.head_tags_for_pact_publication(self).collect(&:name) end def consumer_version_tags diff --git a/spec/lib/pact_broker/pacts/pact_publication_spec.rb b/spec/lib/pact_broker/pacts/pact_publication_spec.rb index e9263b383..b72858448 100644 --- a/spec/lib/pact_broker/pacts/pact_publication_spec.rb +++ b/spec/lib/pact_broker/pacts/pact_publication_spec.rb @@ -113,9 +113,11 @@ module Pacts .create_pact .create_consumer_version("5.6.7") .create_consumer_version_tag("no") + .create_consumer("Foo2") + .create_consumer_version("3.4.5") + .create_consumer_version_tag("yes", comment: "actually no, just here to make sure it selects the right one") end - let(:td) { TestDataBuilder.new } let(:pact_publication) { PactPublication.find(id: td.pact.id) } context "when the pact is the latest for a tag" do