# Rake task for merging users

**URL:** https://meta.discourse.org/t/rake-task-for-merging-users/89086
**Category:** Announcements
**Tags:** new-feature, merge-user
**Created:** [March 1, 2018, 12:56pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086 "2018-03-01T12:56:29Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [March 1, 2018, 12:56pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/1 "2018-03-01T12:56:29Z")

</div>

As of [Discourse 2.5.0.beta3](https://meta.discourse.org/t/discourse-2-5-0-beta3-release-notes/148766), site admins can merge non-staff users without needing to access the console. For security, staff users will still need to be merged via the console.

Visit the user admin page, and select “Merge” at the bottom of the page.  
 ![image](https://global.discourse-cdn.com/meta/original/4X/9/a/9/9a947b005ca785b088b8fd25443dace417dc0cd7.png)

Enter the username you want the account to be merged into, and click “Transfer & Delete @username” to start the merge process.

 ![image](https://global.discourse-cdn.com/meta/original/3X/f/1/f1b05468b020ced2b1577614bbf0510d34f64a6c.png)

* * *

The rake task for merging users is now available on `tests-passed`. ☀

[https://github.com/discourse/discourse/commit/7a2183e8ab97c26464da541014ba1f2e69669a82](https://github.com/discourse/discourse/commit/7a2183e8ab97c26464da541014ba1f2e69669a82)

Users can be merged by executing

```bash
rake users:merge['source_username','target_username']

```

(note: ensure there is no space before/after the comma)

This merges the data of the `source user` into the `target user` before it **deletes** the `source user`. The content of 45 tables gets merged, so depending on the amount of data associated with the `source user` this process can take a while.

**Plugin authors** can hook into the merge process by handling the `:merging_users` event. I’ve already implemented it for the polls plugin, which merges the votes of the two merged users.

**Known problems:**

1. Incoming links that still reference the `source user` (e.g. `https://talk.example.com/t/some-topic/17/3?u=source_username`) won’t be associated with the `target_user`.

2. A user can have only one shadow user (from the `allow anonymous posting` feature). So, if both merged users had a shadow user, then the one owned by the `source user` will be lost… well, it’s still there, but not associated with an existing user anymore.

---

<div class="post-metadata">

### Author: ![mcwumbly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcwumbly/32/103861_2.png) [@mcwumbly](https://meta.discourse.org/u/mcwumbly)
#### Post date: [March 1, 2018, 3:51pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/2 "2018-03-01T15:51:15Z")

</div>

> [@gerhard](#):
>
> It’s essentially based on my idea posted in Update quotes and mentions when username is changed.

Ooh… That’s the most exciting part of this to me.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [March 2, 2018, 12:16am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/3 "2018-03-02T00:16:45Z")

</div>

We should try this out on some of the accounts at [rubytalk.org](http://rubytalk.org) … a great little test site, Matz has like 5 emails.

---

<div class="post-metadata">

### Author: ![mattbr](https://avatars.discourse-cdn.com/v4/letter/m/9de0a6/32.png) [@mattbr](https://meta.discourse.org/u/mattbr)
#### Post date: [March 8, 2018, 9:20pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/4 "2018-03-08T21:20:30Z")

</div>

Thank you for this feature, it is huge for my use case! I am currently porting our forums from phpBB to Discourse and wanted to use SSO via a custom provider. Since we could not easily link SSO accounts to our legacy accounts and works flawlessly!

If anyone else is going to use this make a note of this:

`rake users:merge['mattbr_sso', 'mattbr_legacy']` will not work as expected, the SSO will not go through. However:

`rake users:merge['mattbr_legacy', 'mattbr_sso']` works perfectly and allows you to migrate all the posts into the SSO account.

Thanks for the feature 🙂

---

<div class="post-metadata">

### Author: ![frictionel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/frictionel/32/299701_2.png) [@frictionel](https://meta.discourse.org/u/frictionel)
#### Post date: [March 26, 2018, 8:57pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/5 "2018-03-26T20:57:57Z")

</div>

I’m super excited about this, but can’t see any mention of webhooks in this topic. Is this planned @gerhard?

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [March 26, 2018, 10:04pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/6 "2018-03-26T22:04:07Z")

</div>

How are webhooks relevant to this?

---

<div class="post-metadata">

### Author: ![frictionel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/frictionel/32/299701_2.png) [@frictionel](https://meta.discourse.org/u/frictionel)
#### Post date: [March 26, 2018, 10:30pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/7 "2018-03-26T22:30:26Z")

</div>

When using the ‘User Event’-webhook `created` or `login` (or `approved`?) the duplicates will be existent on a connected site as well and one might want an automatism to clean them up as well, if the connected site supports that.

I haven’t used webhooks yet but plan to. On my connected site (using Discourse as SSO provider) the users are only created at first login for now.  
`+` I had duplicate users in my old forum before migrating to Discourse which I was looking forward to consolidate once this feature becomes available.

---

<div class="post-metadata">

### Author: ![JagWaugh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagwaugh/32/69335_2.png) [@JagWaugh](https://meta.discourse.org/u/JagWaugh)
#### Post date: [April 30, 2018, 5:11am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/8 "2018-04-30T05:11:52Z")

</div>

I had another user question about this today, He also asked about the “Created” field in his profile.

1. Is this function going to be implemented in the GUI, or will it stay a rake task?
2. Will (or has) the rake task be(en) changed to handle mentions and quotes?
3. Would it be possible to set “Created” to the date of the oldest owned post?

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [April 30, 2018, 9:15am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/9 "2018-04-30T09:15:36Z")

</div>

> [@JagWaugh](#):
>
> Is this function going to be implemented in the GUI, or will it stay a rake task?

It will stay a rake task for now.

> [@JagWaugh](#):
>
> Will (or has) the rake task be(en) changed to handle mentions and quotes?

Yes, it will. I should be able to make this happen for the 2.0 release.

> [@JagWaugh](#):
>
> Would it be possible to set “Created” to the date of the oldest owned post?

You will have to update the user’s `created_at` manually if you want to set it to the oldest post. The merge process uses the `created_at` from either the source or target user – whatever date is earlier.

---

<div class="post-metadata">

### Author: ![barryvan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/barryvan/32/82635_2.png) [@barryvan](https://meta.discourse.org/u/barryvan)
#### Post date: [May 2, 2018, 12:55am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/10 "2018-05-02T00:55:10Z")

</div>

> [@gerhard](#):
>
> It will stay a rake task for now.

This being the case, if as a hosted customer I have accounts to be merged, should I ping the details through to the Discourse team for actioning?

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [May 2, 2018, 1:13am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/11 "2018-05-02T01:13:18Z")

</div>

Sure that sounds fine. We also need to exercise the feature internally to make sure it is working right.

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [May 16, 2018, 9:27pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/12 "2018-05-16T21:27:43Z")

</div>

Quick update: Merging users now updates mentions, quotes and avatars in posts and revisions. 🎉

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [May 18, 2018, 9:05pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/13 "2018-05-18T21:05:26Z")

</div>

Any chance the staff action log could better show what happens to users when they are merged? Here’s how it looks now - just shows that system has deleted the user but no context. The details only show some info about the user that got deleted as a result of the merge.

 ![06%20PM](https://global.discourse-cdn.com/meta/original/3X/f/8/f8f254a0cd37221bc118d30cc87276c6c572f462.png)

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [May 18, 2018, 11:16pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/14 "2018-05-18T23:16:59Z")

</div>

Sure what do you think @gerhard?

---

<div class="post-metadata">

### Author: ![JagWaugh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagwaugh/32/69335_2.png) [@JagWaugh](https://meta.discourse.org/u/JagWaugh)
#### Post date: [May 19, 2018, 6:57am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/15 "2018-05-19T06:57:28Z")

</div>

How about adding a staff note along the lines of “ **Username** with **email** was merged to this account, _ **date** _”

This is what I did when I was merging accounts manually. Probably more work than a staff action log entry, but might be useful information at some point later.

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [June 4, 2018, 9:51am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/16 "2018-06-04T09:51:39Z")

</div>

@gerhard we should make sure the task is logged in the staff logs if possible, per above ↑ ↑

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [June 4, 2018, 9:59am UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/17 "2018-06-04T09:59:03Z")

</div>

I’m currently writing my todo list for this week and it’s already on it. 🙂

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [June 4, 2018, 5:58pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/18 "2018-06-04T17:58:08Z")

</div>

Is there an easy way to change which email address is primary?

Here’s my use case:

imported user with email [user@defunctdomain.com](mailto:user@defunctdomain.com) emails from [user@fancynewemail.com](mailto:user@fancynewemail.com) which creates a staged user. After a few PMs with the staged user, I merge the accounts, but the primary address is still the old one. And from the web interface I can’t change the email in his profile because it’s already taken. By him.

Perhaps this is a bug in the multiple email address model and not a complaint for here.

The simple solution, which took me much to long to come up with, is to delete the old address.

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [June 4, 2018, 6:07pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/19 "2018-06-04T18:07:47Z")

</div>

Merging users always preserves the existing data of the `target_user`, so the email address of the `source_user` is only added as secondary email address.

> [@pfaffman](#):
>
> delete the old address.

Yeah, that’s the solution.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [June 4, 2018, 6:14pm UTC](https://meta.discourse.org/t/rake-task-for-merging-users/89086/20 "2018-06-04T18:14:01Z")

</div>

Is there something easier that I should do?  
I need to keep the old username with the new email. The staged user is the real problem. Perhaps I should just delete the staged user, but then I don’t have an easy way to reply to them to tell them what happened.

It’s pretty cumbersome to merge[‘newname\_newemail’,'oldname\_bogusemail"] and then have to do something like

```ruby
u=User.find_by_username['oldname_bogusemail']
ue=UserEmail.where(user_id: u.id)
ue[0].destroy
ue[1].active=true
ue[1].save

```

is there some easier way that I’m missing?

[Next page](https://meta.discourse.org/t/rake-task-for-merging-users/89086.md?page=2)
