{"id":18103145,"url":"https://github.com/allenwq/devise-multi_email","last_synced_at":"2026-04-05T23:07:16.735Z","repository":{"id":3185686,"uuid":"48675849","full_name":"allenwq/devise-multi_email","owner":"allenwq","description":"✉️ Let devise support multiple emails (authenticatable, confirmable and validatable).","archived":false,"fork":false,"pushed_at":"2026-03-31T13:09:57.000Z","size":439,"stargazers_count":78,"open_issues_count":3,"forks_count":30,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-31T15:08:24.711Z","etag":null,"topics":["devise","rails","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allenwq.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2015-12-28T05:37:55.000Z","updated_at":"2026-03-31T13:10:43.000Z","dependencies_parsed_at":"2023-07-07T11:33:30.824Z","dependency_job_id":null,"html_url":"https://github.com/allenwq/devise-multi_email","commit_stats":{"total_commits":158,"total_committers":14,"mean_commits":"11.285714285714286","dds":0.5696202531645569,"last_synced_commit":"39c4bd976b3d0d78c01da37a03c507257db01b49"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/allenwq/devise-multi_email","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenwq%2Fdevise-multi_email","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenwq%2Fdevise-multi_email/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenwq%2Fdevise-multi_email/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenwq%2Fdevise-multi_email/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allenwq","download_url":"https://codeload.github.com/allenwq/devise-multi_email/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenwq%2Fdevise-multi_email/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devise","rails","ruby"],"created_at":"2024-10-31T22:10:33.982Z","updated_at":"2026-04-05T23:07:16.729Z","avatar_url":"https://github.com/allenwq.png","language":"Ruby","readme":"# Devise::MultiEmail [![Build Tests](https://github.com/mgmodell/devise-multi_email/actions/workflows/ruby_spec.yml/badge.svg)](https://github.com/mgmodell/devise-multi_email/actions/workflows/ruby_spec.yml) [![Coverage # Status](https://coveralls.io/repos/mgmodell/devise-multi_email/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/mgmodell/devise-multi_email?branch=master) [![Dependabot Updates](https://github.com/mgmodell/devise-multi_email/actions/workflows/dependabot/dependabot-updates/badge.svg)](https://github.com/mgmodell/devise-multi_email/actions/workflows/dependabot/dependabot-updates)\n\nLetting [Devise](https://github.com/plataformatec/devise) support multiple emails, allows you to:\n- Login with multiple emails\n- Send confirmations to multiple emails\n- Recover the password with any of the emails\n- Validations for multiple emails\n\n`:multi_email_authenticatable`, `:multi_email_confirmable`, `:multi_email_recoverable` and `:multi_email_validatable` are provided by _devise-multi-email_.\n\n## Getting Started\n\nAdd this line to your application's `Gemfile`:\n\n```ruby\ngem 'devise-multi_email'\n```\n\nSuppose you have already setup Devise, your `User` model might look like this:\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  devise :database_authenticatable, :registerable\nend\n```\n\nIn order to let your `User` support multiple emails, with _devise-multi-email_ what you need to do is just:\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :emails\n\n  # Replace :database_authenticatable, with :multi_email_authenticatable\n  devise :multi_email_authenticatable, :registerable\nend\n\nclass Email \u003c ActiveRecord::Base\n  belongs_to :user\nend\n```\n\nNote that the `:email` column should be moved from `users` table to the `emails` table, and a new `primary` boolean column should be added to the `emails` table (so that all the emails will be sent to the primary email, and `user.email` will give you the primary email address). Your `emails` table's migration should look like:\n\n```ruby\ncreate_table :emails do |t|\n  t.integer :user_id\n  t.string :email\n  t.boolean :primary\n end\n```\n\nYou can choose whether or not users can login with an email address that is not the primary email address.\n\n```ruby\nDevise::MultiEmail.configure do |config|\n  # Default is `false`\n  config.only_login_with_primary_email = true\nend\n```\n\nThe `autosave` is automatically enabled on the `emails` association by default. This is to ensure the `primary`\nflag is persisted for all emails when the primary email is changed. When `autosave` is not enabled on the association,\nonly new emails are saved when the parent (e.g. `User`) record is saved. (Updates to already-persisted email records\nare not saved.)\n\nIf you don't want `autosave` to be enabled automatically, you can disable this feature. What this will do is\nenable alternative behavior, which adds an `after_save` callback to the parent record and calls `email.save` on each email\nrecord where the `primary` value has changed.\n\n```ruby\nDevise::MultiEmail.configure do |config|\n  # Default is `true`\n  config.autosave_emails = false\nend\n```\n\n### Configure custom association names\n\nYou may not want to use the association `user.emails` or `email.users`. You can customize the name of the associations used. Add your custom configurations to an initializer file such as `config/initializers/devise-multi_email.rb`.\n\n_Note: model classes are inferred from the associations._\n\n```ruby\nDevise::MultiEmail.configure do |config|\n  # Default is :user for Email model\n  config.parent_association_name = :team\n  # Default is :emails for parent (e.g. User) model\n  config.emails_association_name = :email_addresses\n  # Default is :primary_email_record\n  config.primary_email_method_name = :primary_email\nend\n\n# Example use of custom association names\nteam = Team.first\nemails = team.email_addresses\n\nemail = EmailAddress.first\nteam = email.team\n```\n\n## Confirmable with multiple emails\n\nSending separate confirmations to each email is supported. What you need to do is:\n\nDeclare `devise :multi_email_confirmable` in your `User` model:\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :emails\n\n  # You should not declare :confirmable and :multi_email_confirmable at the same time.\n  devise :multi_email_authenticatable, :registerable, :multi_email_confirmable\nend\n```\n\nAdd `:confirmation_token`, `:confirmed_at` and `:confirmation_sent_at` to your `emails` table:\n\n```ruby\ncreate_table :emails do |t|\n  t.integer :user_id\n  t.string :email\n  t.boolean :primary, default: false\n\n  ## Confirmable\n  t.string :unconfirmed_email\n  t.string :confirmation_token\n  t.datetime :confirmed_at\n  t.datetime :confirmation_sent_at\nend\n```\n\nThen all the methods in Devise confirmable are available in your `Email` model. You can do `email#send_confirmation_instructions` for each of your email. And `user#send_confirmation_instructions` will be delegated to the primary email.\n\n## Validatable with multiple emails\n\nDeclare `devise :multi_email_validatable` in the `User` model, then all the user emails will be validated:\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :emails\n\n  # You should not declare :validatable and :multi_email_validatable at the same time.\n  devise :multi_email_authenticatable, :registerable, :multi_email_validatable\nend\n```\n\nYou can find the detailed configurations in the [rails 5 example app](https://github.com/allenwq/devise-multi_email/tree/master/examples/rails5_app).\n\n## Recoverable with multiple emails\n\nDeclare `devise :multi_email_recoverable` in your `User` model to enable password reset support that is aware of multiple emails:\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :emails\n\n  devise :multi_email_authenticatable, :multi_email_confirmable,\n         :multi_email_recoverable, :multi_email_validatable\nend\n```\n\n### Controlling which address receives the password reset email\n\nBy default, the password reset email is always sent to the **primary email address**, regardless of which email the user typed into the forgot-password form.\n\nYou can change this globally with the `password_reset_email_strategy` option:\n\n```ruby\nDevise::MultiEmail.configure do |config|\n  # :primary (default) — always send to the user's primary email address.\n  # :request           — send to the email the user typed in the forgot-password form.\n  config.password_reset_email_strategy = :request\nend\n```\n\n#### Per-call override\n\nPass the `email:` keyword to the public `send_reset_password_instructions` method to override the global strategy for that call only. When no keyword is given, it falls back to the configured strategy (`:primary` by default).\n\n```ruby\n# Uses global strategy (default: :primary)\nuser.send_reset_password_instructions\n\n# Explicitly send to the primary email, ignoring global config\nuser.send_reset_password_instructions(email: :primary)\n\n# Explicitly send to the email the user entered in the forgot-password form\nuser.send_reset_password_instructions(email: :request)\n```\n\n## What's more\n\nThe gem works with all other Devise modules as expected -- you don't need to add the \"multi_email\" prefix.\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  devise :multi_email_authenticatable, :multi_email_confirmable, :multi_email_validatable, :lockable,\n         :multi_email_confirmable, :registerable, :rememberable, :timeoutable, :trackable\nend\n```\n\n## Issues\n\nYou need to implement add/delete emails for a user as well as set/unset \"primary\" for each email.\n\nYou can do `email.send_confirmation_instructions` for each email individually, but you need to handle that logic in some place (except for the primary email, which is handled by Devise by default). e.g. After a new email was added by a user, you might want to provide some buttons in the view to allow users to resend confirmation instructions for that email.\n\n## Wiki\n\n[Migrating existing user records](https://github.com/allenwq/devise-multi_email/wiki/Migrating-existing-user-records)\n\n## Development\n\nAfter checking out the repo, run `bundle install` to install dependencies.\n\nThen, run `bundle exec rake` to run the RSpec test suite.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/allenwq/devise-multi_email. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.\n\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallenwq%2Fdevise-multi_email","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallenwq%2Fdevise-multi_email","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallenwq%2Fdevise-multi_email/lists"}