Bulk move many topics from one category to another

Continuing the discussion from Move topics to new category:

Is there a query to bulk move many topics from one category to another? I want to consolidate many categories into one category and would like to make the move quickly and all at once, and also not bump the topics.

Bonus: also want to tag topics first with a category-equivalent tag before moving them.

Grateful for any queries or recipes. Many thanks! I’d even write it up as a #howto topic if it’s good. :slightly_smiling:

4 Likes

If you want to move all the topics from one category to another

Topic.where(category_id: <from_category_id>).update_all(category_id: <to_category_id>)

where “<from_category_id>” is the id of the origin category and “<to_category_id>” is the destination category.

If you want to move some topics from one category to another

topic_ids = [<topic_id_1>, <topic_id_2>, ...]
Topic.where(id: topic_ids).update_all(category_id: <to_category_id>)

where “<topic_id_1>, <topic_id_2>, ...” is a list of the topic ids you want to move.

If you execute either of these, category stats will be wrong but should fix themselves after a day.

10 Likes

thanks, @zogstrip! Much appreciated. What about tagging the topics first? Can you provide the query for that?

Update: I ended up doing the bulk move using the command you suggest, which appears to have worked perfectly. W00t! Thank you!

A little digging this morning revealed that @riking had also suggested a similar rails command in another topic:

https://meta.discourse.org/t/best-way-to-combine-merge-categories-when-importing-topics/21353/2?u=tobiaseigen

There is also a topic I found for ‘converting categories to tags’. That would be a great place to share commands for bulk adding tags if it’s possible, as suggested by @erlend_sh.

https://meta.discourse.org/t/converting-categories-to-tags/33992/13?u=tobiaseigen

3 Likes

Whoa, this discovery solved my problem.

I’m golden. I can make bulk changes to tags and categories via discourse UI without bumping the topic. :thumbsup:

3 Likes

@zogstrip a downside to the query method of bulk moving topics into new categories is this:

Can’t delete this category because topic count is 200

I am trying to delete the old category (4 days later) but it won’t let me because of this message. Can you help me fix this?

Also, this method also had me move the “about this category” topic which also breaks some functionality.

So… conclusion is that using the bulk edit tags via the discourse UI is safer. :slight_smile:

2 Likes

This should solve your count problem

Category.where(id: <category_id>).update_all(topic_count: Topic.where(category_id: <category_id>).count)
6 Likes

awesome - many, many thanks. that worked. I am so glad to have this bit of housekeeping taken care of.

Here, have a cute panda playing in the snow.

3 Likes

Panda…monium :panda_face:

4 Likes

For anyone else who comes across this thread and doesn’t understand how to execute them, see the post below. It is linked to above also, but it’s not immediately obvious from the snippet that it shows exactly what to do, so click through and it will be clear.

https://meta.discourse.org/t/best-way-to-combine-merge-categories-when-importing-topics/21353/2?u=undecidedadmin

3 Likes

OK, this is how to do it the proper way (had issues with the last post):

  1. Visit https://yourdomain.example/site.json
  2. Find your category ID
  3. Run this in your console:
    1 and 15 are example IDs
cd /var/discourse
./launcher enter app
rails c 
Topic.where(category_id: 1).update_all(category_id: 15)
exit
exit
5 Likes

Hey @tobiaseigen it looks like this url no longer works.

How can I convert a category of posts to adding a tag to each of the posts?

@enoch85 Thank you so much for the commands you outlined:

Summary

Is there a way you could infuse a command to first assign a specific tag to every topic in a category, before migrating all topics to a new category?

1 Like

You can do this via the UI. Just go to the category and select all topics, then select the wrench to access the bulk options. Add the tag you want and then change the category.

I did this recently and there was one unintended consequence. People who were watching the category were notified of the change. Not sure if this can be somehow avoided.

4 Likes

From this topic:

I saw different methods; so is there any difference between these two commands?

Topic.where(category_id: 15).update_all(category_id: 6)
rake categories:move_topics[15,6]

Also in the example provided in the link,

topic_ids = [12,16,29]
cat_to = Category.find_by_slug('faq')
Topic.where(id: topic_ids).update_all(category_id: cat_to.id)
Category.update_stats

It uses .update_stats. Is it optional?

4 Likes

This is perfect!!! Thank you!

3 Likes

I accidentally transfered the “About News & Events” post using the bulk method above, to my “Disussions” category.

I made some changes and decided to move that topic back to its home, in the “News & Events” category but every time I try to save, it just reverts and stays in the “Discussions” category, as seen in this video…

Any ideas on how to fix this?

What could I enter into terminal to try to change it back?

2 Likes

Find the topic id for the ‘About’ topic you want to move back, then use rails c

topic_ids = [<topic_id>]
Topic.where(id: topic_ids).update_all(category_id: <category_id>)
4 Likes

Spot on @md-misko! Thanks for the snippet!

Here’s exactly what I did and I was able to move a specific topic to another category:
(where my topic id was 16 and the category I wanted to move this topic to was 5)

cd /var/discourse
./launcher enter app
rails c 
topic_ids = [16]
Topic.where(id: topic_ids).update_all(category_id: 5)
exit
exit
exit
5 Likes

It’s likely running on a daily or weekly job, so it’s optional if you are okay with stats being slightly off for up to a week.

3 Likes