This is only a breaking change if you have built your own key types. This is being released as a bug fix since the ReturningKeyType
has not worked correctly since 5.0.0
Please upgrade to a supported engine.
This means for scopes, you must call addSubselect
off of the passed in builder object.
Instead of this:
the scopes should be called on the passed in Builder instance:
This isn't a breaking change that will affect most people. In fact, it will most likely improve your code.
Previously, when using scopes, whereHas
, or whereDoesntHave
, you were fully responsible for the wrapping of your where statements. For example, the following query:
with the following scopes defined:
would generate the following SQL:
The problem with this statement is that the OR
can short circuit the active
check.
The fix is to wrap the LIKE
statements in parenthesis. This is done in qb using a function callback to where
. Adding this nesting inside our scope will fix this problem.
But this was easy to miss this. This is because you are in a completely different file than the built query. It also breaks the mental model of a scope as an encapsulated piece of SQL code.
In Quick 4.0.0, scopes, whereHas
, and whereDoesntHave
will automatically group added where clauses when needed. That means our original example now produces the SQL we probably expected.
Grouping is not needed if there is no OR
combinator. In these cases no grouping is added.
If you had already wrapped your expression in a group inside the scope, whereHas
, or whereDoesntHave
call, nothing changes. Your code works as before. The OR
combinator check only works on the top most level of added where clauses. Additionally, if you do not add any where clauses inside your scope, nothing changes.
The breaking change part is if you were relying on these statements residing at the same level without grouping. If so, you will need to group your changes into a single scope where you control the grouping or do the querying at the builder level outside of scopes.
Please migrate to a supported engine.
Virtual Inheritance allowed you to use a quick
annotation on your entity instead of extending quick.models.BaseEntity
. This was hardly used and didn't offer any benefit to extending using traditional inheritance. Additionally, removing the support allows us to clean up the code base by removing duplicate code paths.
If any of your entities are using the quick
annotation, instead have them extends="quick.models.BaseEntity"
.
From the early days of Quick, developers have wanted to have accessors="true"
on their entities. Because of this, Quick supported defining entities both with and without accessors. However, just as with virtual inheritance, it created two code paths that could hide bugs and make it hard to follow the code. In Quick 3.0.0, accessors="true"
is required on all entities. If it is omitted, a helpful error message is thrown to remind you. This will help immensely in simplifying the code base. (In fact, just introducing this requirement helped find two bugs that were only present when using accessors.)
Ensure all entities have accessors="true"
in their component metadata.
Use NullKeyType
instead.
Previously, the only valid cast type was casts="boolean"
. In introducing the new Casts system, the boolean cast was refactored to use the same system. For this reason, any casts="boolean"
needs to be changed to casts="BooleanCast@quick"
In previous versions, the value passed to defaultGrammar
was used to look up a mapping in the @qb
namespace. This made it difficult to add or use grammars that weren't part of qb. (You could get around this be registering your custom grammar in the @qb
namespace, but doing so seemed strange.)
To migrate this code, change your defaultGrammar
to be the full WireBox mapping in your moduleSettings
:
It no longer accepts any entities or columns. Rather, it accepts an array of relationships to walk "through" to end up at the desired entity.
Here's how the old syntax would be used to define the relationship between Country
and Post
.
This same relationship now needs to be defined in terms of other relationships, like so.
This approach does require a relationship defined for each level, but it works up and down any number of relationships to get to your desired entity.
To update the foreign key of a belongsTo
relationship you use the associate
method. In the past, it was possible to associate a new, unsaved child entity to its parent using this method.
In an attempt to provide more helpful error messages, this behavior is no longer possible. You can achieve the same effect in one of two ways.
The first is to manually assign the foreign keys:
While this works, it breaks the encapsulation provided by the relationship.
The second approach is to use the hasOne
or hasMany
side of the relationship to create the new child entity:
If you have all the data handy in a struct, you can use the create
method for a more concise syntax.
This is the recommended way of creating these components.
This brings the API in line with the other methods referencing attributes.
Compound key support required some method and parameter name changes. Although the list seems extensive, you will likely not need to change anything in your code unless you have extended built-in Quick components. (You will see many relationship parameter name changes. Note that the function you call to define a relationship is a function on the BaseEntity
and has not changed its signature.)
BaseEntity.cfc:
retrieveQualifiedKeyName : String
-> retrieveQualifiedKeyNames : [String]
keyName : String
-> keyNames : [String]
keyColumn : String
-> keyColumns : [String]
keyValue : String
-> keyValues : [String]
AutoIncrementingKeyType.cfc
This cannot be used with composite primary keys
BaseRelationship.cfc
getKeys
now takes an array of keys
as the second argument
getQualifiedLocalKey : String
-> getQualifiedLocalKeys : [String]
getExistenceCompareKey : String
-> getExistenceCompareKeys : [String]
BelongsTo.cfc
init
arguments have changed
foreignKey : String
-> foreignKeys : [String]
localKey : String
-> localKeys : [String]
getQualifiedLocalKey : String
-> getQualifiedLocalKeys : [String]
getExistenceCompareKey : String
-> getExistenceCompareKeys : [String]
BelongsToMany.cfc
init
arguments have changed
foreignPivotKey : String
-> foreignPivotKeys : [String]
relatedPivotKey : String
-> relatedPivotKeys : [String]
parentKey : String
-> parentKeys : [String]
relatedKey : String
-> relatedKeys : [String]
getQualifiedRelatedPivotKeyName : String
-> getQualifiedRelatedPivotKeyNames : [String]
getQualifiedForeignPivotKeyName : String
-> getQualifiedForeignPivotKeyNames : [String]
getQualifiedForeignKeyName : String
-> getQualifiedForeignKeyNames : [String]`
HasManyThrough.cfc
This component now extends quick.models.Relationships.HasOneOrManyThrough
init
arguments are now as follows:
related
: The related entity instance.
relationName
: The WireBox mapping for the related entity.
relationMethodName
: The method name called to retrieve this relationship.
parent
: The parent entity instance for the relationship.
relationships
: An array of relationships between the parent entity and the related entity.
relationshipsMap
: A dictionary of relationship name to relationship component.
The following methods no longer exist:
getQualifiedFarKeyName
getQualifiedForeignKeyName
getQualifiedFirstKeyName
getQualifiedParentKeyName
HasOneOrMany.cfc
init
arguments have changed
foreignKey : String
-> foreignKeys : [String]
localKey : String
-> localKeys : [String]
getParentKey : any
-> getParentKeys : [any]
getQualifiedLocalKey : String
-> getQualifiedLocalKeys : [String]
getQualifiedForeignKeyName : String
-> getQualifiedForeignKeyNames : [String]
PolymorphicBelongsTo.cfc
init
arguments have changed
foreignKey : String
-> foreignKeys : [String]
localKey : String
-> localKeys : [String]
PolymorphicHasOneOrMany.cfc
init
arguments have changed
id : String
-> ids : [String]
localKey : String
-> localKeys : [String]
Quick 2.0 brings with it a lot of changes to make things more flexible and more performant. This shouldn't take too long — maybe 2-5 minutes per entity.
There were some common name clashes between internal Quick properties and custom attributes of your entities (the most common being fullName
). All Quick internals have been obfuscated to avoid this situation. If you relied on these properties, please consult the following table below for the new property names.
If you are renaming your primary keys in your entities, you will have to change your key definition from variables.key = "user_id";
to variables._key
= "user_id";
See Defining an Entity for details.
Additionally, some method names have also changed to avoid clashing with automatically generated getters and setters. Please consult the table below for method changes.
Lastly, the following properties and methods have been removed: