Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.withCount() on hasManyThrough() throws arrays do not have the same lengths [4,2] when intermediary relationship has a compound key #262

Open
MordantWastrel opened this issue Feb 21, 2025 · 0 comments

Comments

@MordantWastrel
Copy link
Contributor

We have an entity, qCompetitionSeasonDivision that translates to 'settings for this sports program (competition) for this division for this season' and a relationship where we want to see how many people have registered for that program in that division in that season.

Using a scope with .withCount() causes arrayZipEach() to throw The arrays do not have the same length [[4,2]].

Stripped down entity and relationships:

component table="competition_seasonal_divisional" extends="model.q.inLeagueBaseEntity" accessors=true {
	property name="compSeasonDivUID" column="compSeasonDivUID" type="string" sqltype="idstamp";
	property name="competitionUID"   column="competitionUID"   type="string" sqltype="idstamp";
	property name="seasonUID"        column="seasonUID"        type="string" sqltype="idstamp";
	property name="divID"            column="divID"            type="string" sqltype="idstamp";

    
function v_compSeasonDiv_forAllSourceCompsIncludingSelfSource() {
		return hasMany(
			relationName = "q_v_compSeasonDiv_forAllSourceCompsIncludingSelfSource",
			foreignKey = "compSeasonDivUID",
			localKey = "compSeasonDivUID"
		);
	}

	function competitionRegistrationsIncludingSourcedCompetitions() {
		return hasManyThrough(
			relationships = [ "v_compSeasonDiv_forAllSourceCompsIncludingSelfSource", "competitionRegistrations" ]
		)
	}

The intermediary entity:

component extends="model.q.inLeagueBaseEntity" table="v_competition_seasonal_divisional_forAllSourceCompsIncludingSelfSource" accessors=true {

	property name="compSeasonDivUID"     type="guid"    sqltype="idstamp" readonly=true update=false;
	property name="competitionUID"       type="guid"    sqltype="idstamp" readonly=true update=false;
    property name="seasonUID"            type="guid"    sqltype="idstamp" readonly=true update=false;
	property name="divID"                type="guid"    sqltype="idstamp" readonly=true update=false;
	property name="sourceCompetitionUID" type="guid"    sqltype="idstamp" readonly=true update=false;

	// This definition of the key is not true, but is required to play nice with hasOneOrManyThrough in left side of this "join" table (i.e. in compSeasonDiv).
	// Actual candidate keys are:
	//  - (sourceCompetitionUID, compSeasonDivUID, sourceCompetitionUID)
	//  - (sourceCompetitionUID, competitionUID, seasonUID, divID, sourceCompetitionUID)
	variables._key = 'compSeasonDivUID'

    function competitionRegistrations() {
        return hasMany(
            relationName = "qCompetitionRegistration",
            foreignKey = ["competitionUID", "seasonUID", "divID"],
            localKey = ["sourceCompetitionUID", "seasonUID", "divID"]
        )
    }

	function compSeasonDiv() {
		return belongsTo(
			relationName = "qCompetitionSeasonDivision",
			foreignKey = ["competitionUID", "seasonUID", "divID"],
            localKey = ["sourceCompetitionUID", "seasonUID", "divID"]
		)
	}
}

The following scope throws the error:

function scopeWithCurrentActiveRegistrationsCountIncludingSourcedCompetitions( qb ) {
		qb.withCount( {
			"competitionRegistrationsIncludingSourcedCompetitions as currentActiveRegistrationsCountIncludingSourcedCompetitions" : function(
				qCompetitionRegistration
			) {
				qCompetitionRegistration
					.where( ( qb ) => {
						qb.orWherePaid( 1 )
							.orWhereNotNull( "awaitingAsyncPaymentCompletion" )
					} )
					.whereCanceled( 0 )
			}
		} )
	}

Stack trace:

modules/quick/models/Relationships/BaseRelationship.cfc:609
modules/quick/models/Relationships/HasManyDeep.cfc:217
/root/modules/quick/models/QuickQB.cfc:990
modules/qb/models/Query/QueryBuilder.cfc:1661
modules/quick/models/QuickBuilder.cfc:775
modules/quick/models/Relationships/HasManyDeep.cfc:219
modules/quick/models/QuickBuilder.cfc:265
modules/quick/models/BaseEntity.cfc:1291
modules/quick/models/QuickBuilder.cfc:270
modules/quick/models/BaseEntity.cfc:3079
modules/quick/models/QuickBuilder.cfc:271
model/q/Competition/qCompetitionSeasonDivision.cfc:155
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant