Fixed actor merge failing if target actor is already assigned to some scenes. Linked ID in actors admin to actor page.

This commit is contained in:
2026-06-19 02:18:02 +02:00
parent bad116cdc0
commit 4e8356b072
2 changed files with 22 additions and 5 deletions

View File

@@ -45,7 +45,13 @@
:key="`actor-${actor.id}`" :key="`actor-${actor.id}`"
class="actor" class="actor"
> >
<td class="actor-id ellipsis">{{ actor.id }}</td> <td class="actor-id ellipsis">
<a
:href="`/actor/${actor.id}/${actor.slug}`"
target="_blank"
class="nolink"
>{{ actor.id }}</a>
</td>
<td <td
v-tooltip="actor.entity?.name || 'Global'" v-tooltip="actor.entity?.name || 'Global'"

View File

@@ -599,7 +599,8 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
const trx = await knex.transaction(); const trx = await knex.transaction();
let mergedProfiles; let mergedProfiles;
let mergedScenes; let mergedSceneActors;
let existingSceneActors;
try { try {
const [existingProfiles] = await Promise.all([ const [existingProfiles] = await Promise.all([
@@ -619,20 +620,30 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
.returning('id'), .returning('id'),
]); ]);
existingSceneActors = await trx('releases_actors')
.where('actor_id', targetActorId);
mergedProfiles = await trx('actors_profiles') mergedProfiles = await trx('actors_profiles')
.update('actor_id', targetActorId) .update('actor_id', targetActorId)
.whereIn('actor_id', sourceActorIds) .whereIn('actor_id', sourceActorIds)
.whereNotIn('entity_id', existingProfiles.map((profile) => profile.entity_id)) .whereNotIn('entity_id', existingProfiles.map((profile) => profile.entity_id))
.returning('id'); .returning('id');
mergedScenes = await trx('releases_actors') mergedSceneActors = await trx('releases_actors')
.update({ .update({
actor_id: targetActorId, actor_id: targetActorId,
alias_id: knex.raw('actor_id'), alias_id: knex.raw('actor_id'),
}) })
.whereIn('actor_id', sourceActorIds) .whereIn('actor_id', sourceActorIds)
.whereNotIn('release_id', existingSceneActors.map((sceneActor) => sceneActor.release_id)) // can't update entry if target actor already exists alongside source actor
.returning('release_id'); .returning('release_id');
// delete aliased actors for scenes that already had both source/aliased and target actor assigned
const releases = await trx('releases_actors')
.whereIn('release_id', existingSceneActors.map((sceneActor) => sceneActor.release_id))
.whereIn('actor_id', sourceActorIds)
.delete();
await trx.commit(); await trx.commit();
} catch (error) { } catch (error) {
await trx.rollback(); await trx.rollback();
@@ -649,13 +660,13 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
}, { refreshView: false }); }, { refreshView: false });
await Promise.all([ await Promise.all([
syncScenes(mergedScenes.map((scene) => scene.release_id)), syncScenes([...mergedSceneActors.map((sceneActor) => sceneActor.release_id), ...existingSceneActors.map((sceneActor) => sceneActor.release_id)]),
syncActors([targetActorId, ...sourceActorIds]), syncActors([targetActorId, ...sourceActorIds]),
syncStashes('actor', [targetActorId, ...sourceActorIds]), syncStashes('actor', [targetActorId, ...sourceActorIds]),
]); ]);
return { return {
scenes: mergedScenes.length, scenes: mergedSceneActors.length,
profiles: mergedProfiles.length, profiles: mergedProfiles.length,
}; };
} }