Hi,
I've added versions: { drafts: true } to my Articles collection, which already contains some articles.
After doing it:
I couldn't find anything on the Internet, only one thing on the drafts documentation, but it doesn't work for me to see the "old" articles on Admin UI.
Note regarding adding versions to an existing collection
If you already have a collection with documents, and you opt in to draft functionality after you have already created existing documents, all of your old documents will not have a _status field until you resave them. For this reason, if you are adding versions into an existing collection, you might want to write your access control function to allow for users to read both documents where _status is equal to "published" as well as where _status does not exist.
Do you know how to solve it? Shall I do it via migration script or something else?
The list uses the versions collection, which makes it look like there are no documents even when the database has them. If you make a migration that saves all the documents using payload.update({ _status: 'published', where: {}) it should resave all your docs to have a version history.
thank you very much 💪
I do have same issue and i can't able to resolve it can you please guide me in details how can i resolve this ?
Help will be much appreciated !!
@rafalkowalewski can you help me on it?
@komal1220
to be honest - we are not on production still, so I just removed all data in db
but I think it could be fixed just by adding a migration script and resave all of the documents
Thanks @rafalkowalewski . Actually I do have two migration scripts and I'm bit confuse which i have to use . if you have any migration scripts can you please share with me if you don't have any problem?
Thanks!!
@DanRibbens
@komal1220
I haven't created any yet, so I can't help you with that :/
Hi @komal1220 ! I had the same problem and managed to migrate correctly.
After generating your migration file, eg:
pnpm run payload migrate:create ‘add versionning to blog post && xp post’You modify the up() script in /migrations/${theNameOfYourMigration}.ts. In my case, after the await payload.db.drizzle.execute(sql...), I added this:
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
await payload.db.drizzle.execute(sql`...);
await payload.update({
collection: "blogPosts",
where: {},
data: { _status: "published" },
});
}Hope this helps !
The list uses the versions collection, which makes it look like there are no documents even when the database has them. If you make a migration that saves all the documents using
payload.update({ _status: 'published', where: {})it should resave all your docs to have a version history.
This doesn't work. The migration runs successfully but the tables/collections are not created. After removing payload.update, the tables/collections are created
For me the provided solution worked but only when I put suggested code into a separate migration. Combined migration was timing out so I realised that the update script needs to be run in a separate transaction.
Unfortunately, the approach described by @DanRibbens may not work with the SQLite adapter under certain circumstances. Consider a page collection with blocks that are backed by a separate page_blocks table.
The generated migration used drizzle's "insert into new table, drop old table and rename" strategy - I assume it did this because adding versions to the collection automatically changed some required fields from non-nullable to nullable in the database schema and this is one of the many operations that SQLite does not support with ALTER TABLE. However, dropping the table this way cascade-deleted all FK-referenced page_blocks entries.
So then calling
update({collection: 'page', where: {}, data: { _status: 'published'})fixed the page entities by populating the versions table, but the content was gone forever.
I tried to work around this by loading the content before applying the actual migration. This required modifying the drizzle schema because it already reflects the current configuration, rather than the pre-migration one. There is also a latest column in the versions table which doesn't appear to be set automatically this way. If you don't set this, the documents don't show up.
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
const pages = await withPatchedSchema(payload, ({collections}) => {
const pageConfig = collections.find(c => c.slug === 'page')!;
// Revert to pre-drafts configuration
pageConfig.versions = {drafts: false, maxPerDoc: 10};
pageConfig.flattenedFields = pageConfig.flattenedFields.filter(f => !('name' in f) || f.name !== '_status');
}, () => payload.find({collection: 'page', pagination: false}));
// Rest of migration
await db.run(sql`CREATE TABLE...`);
// Populate versions
for (const page of pages.docs) {
await payload.update({collection: 'page', data: {...page, _status: 'published'}, where: {}});
}
await payload.db.drizzle.update(payload.db.tables._page_v).set({latest: 1});
}// Helper to make temporary changes to the Payload collection config.
import { drizzle } from 'drizzle-orm/libsql';
import { Payload, SanitizedConfig } from 'payload';
import { produce, WritableDraft } from 'immer';
const withPatchedSchema = async <T>(payload: Payload, patch: (config: WritableDraft<SanitizedConfig>) => void, callback: () => Promise<T>) => {
const prevConfig = payload.config;
payload.config = produce(payload.config, patch);
await payload.db.init!();
payload.db.drizzle = drizzle(payload.db.client as never, {schema: {
...payload.db.tables,
...payload.db.relations,
}});
const result = await callback();
payload.config = prevConfig;
await payload.db.init!();
payload.db.drizzle = drizzle(payload.db.client as never, {schema: {
...payload.db.tables,
...payload.db.relations,
}});
return result;
}This was definitely a major PITA and my key takeaway is to plan ahead if you think your collection is going to need versions :)
This is horrible DX. How can enabling versions on existing collections cause loss of data? is it not simply moving the data to the version table and fix all foreign keys etc?
For my collection, which supports multiple contentblocks, this is a major PITA.
Star
Discord
online
Get dedicated engineering support directly from the Payload team.