{"id":25397923,"url":"https://github.com/pedrosrc/rails-verification-email","last_synced_at":"2026-05-08T17:38:44.806Z","repository":{"id":276880737,"uuid":"929927705","full_name":"pedrosrc/Rails-Verification-Email","owner":"pedrosrc","description":"Verification Email in Rails without Devise","archived":false,"fork":false,"pushed_at":"2025-02-12T13:39:52.000Z","size":45,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T04:39:38.006Z","etag":null,"topics":["ruby","ruby-on-rails"],"latest_commit_sha":null,"homepage":"https://dev.to/pedroleo/email-verification-with-sent-codes-in-ruby-on-rails-without-devise-479a","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedrosrc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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}},"created_at":"2025-02-09T18:10:00.000Z","updated_at":"2025-02-12T13:49:24.000Z","dependencies_parsed_at":"2025-02-11T00:25:40.883Z","dependency_job_id":"85b6f294-034e-4362-9934-ecd0ef5a73cc","html_url":"https://github.com/pedrosrc/Rails-Verification-Email","commit_stats":null,"previous_names":["pedrosrc/rails-verification-email"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrosrc%2FRails-Verification-Email","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrosrc%2FRails-Verification-Email/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrosrc%2FRails-Verification-Email/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrosrc%2FRails-Verification-Email/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedrosrc","download_url":"https://codeload.github.com/pedrosrc/Rails-Verification-Email/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248345272,"owners_count":21088241,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ruby","ruby-on-rails"],"created_at":"2025-02-15T22:22:42.947Z","updated_at":"2026-05-08T17:38:44.658Z","avatar_url":"https://github.com/pedrosrc.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Verification Email in Rails\n\n## 🚀 Installing the project \n\nTo install the project, follow these steps:\n\n1- Clone Repository:\n```\ngit@github.com:pedrosrc/Rails-Verification-Email.git\n```\n\n2- Install gem's\n\n```\nbundle install\n```\n\n3- Run Migrations\n\n```\nrails db:migrate\n```\n\n## ☕ Using projecty\n\n```\nbin/dev\n```\n## 📚Learning about Mailer\n\nHello, we know that email verification is present in many applications in our daily lives. It is through it that we improve the sender's reputation and, most importantly, prevent identity forgery. Given this, I saw in the Rails community that using Devise is quite common, but what if you wanted to implement something from scratch? How would you do it? Today, I’m going to teach you.\n\nFor this example, I will be using Rails 7.2, SQLite3, and Bcrypt.\n\n## 1. Initial Configuration\nTo create the Rails application, run:\n\n```\nrails new verification-app\ncd verification-app\n```\n**1.1 Create a Model for User**\nRun in your terminal:\n```\nrails generate model User name:string email:string password_digest:string verification_code:string verified:boolean\nrails db:migrate\n```\nChange `app/models/user.rb` to include secure authentication:\n\n```\nclass User \u003c ApplicationRecord\n  has_secure_password\n  before_create :generate_verification_code\n  validates :name, :email, presence: true\n  validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }\n  \n  def generate_verification_code\n    self.verification_code = rand(100000..999999).to_s\n    self.verified = false\n  end\nend\n```\nMethod `generate_verification_code`: This method generates a random verification code (a 6-digit number) whenever a new user is created. The code is stored in the `verification_code` attribute, and the `verified` attribute is set to `false`, indicating that the user has not been verified yet.\n\n## 2. Mailer Configuration\nThe Mailer is the Rails module responsible for facilitating email sending. It allows you to define templates, layouts, and some logic for emails in an organized way.\n\n**2.1 Creating Mailer**\nRun in your terminal:\n\n```\nrails generate mailer UserMailer\n```\nChange `app/mailers/user_mailer.rb` :\n\n```\nclass UserMailer \u003c ApplicationMailer\n  default from: 'youremail@gmail.com'\n  \n  def verification_email(user)\n    @user = user\n    mail(to: @user.email, subject: \"Verification Code\")\n  end\nend\n```\nIn 'youremail@gmail.com', use the email that will be responsible for sending to users. I recommend using it in a credential or environment variable, but in this example, I will make it very explicit.\n\nCreate view `app/views/user_mailer/verification_email.html.erb`:\n\n```\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    @import url('https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css');\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody class=\"bg-gray-100 font-sans leading-normal tracking-normal\"\u003e\n  \u003cdiv class=\"max-w-lg mx-auto my-10 bg-white p-8 rounded-lg shadow-lg\"\u003e\n    \u003ch1 class=\"text-2xl font-bold mb-4\"\u003eVerify your account\u003c/h1\u003e\n    \u003cp class=\"text-lg mb-4\"\u003eHi, \u003c%= @user.name %\u003e!\u003c/p\u003e\n    \u003cp class=\"text-lg mb-4\"\u003eYour verification code is: \u003cstrong class=\"text-blue-500\"\u003e\u003c%= @user.verification_code %\u003e\u003c/strong\u003e\u003c/p\u003e\n    \u003cp class=\"text-lg\"\u003eEnter this code on the verification page to activate your account.\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\nThis view will be the layout of the email that the user will receive. You can style it with Tailwind, as shown in the example. You can also use it in a regular erb structure.\n\n**2.2  SMTP Configuration (Gmail - Tests)**\nIn my application, I chose to use Gmail to send emails, but you can use other services, such as SendGrid (recommended for production). Just configure them according to each one's instructions.\n\nIn the case of Gmail, you need to register an application at the following link and use the password it provides in your Rails Credentials or ENV, if you prefer.\n\n1. Acess: https://myaccount.google.com/apppasswords\n2. Generate a password for your app and use it instead of your real password.\n3. In \"user_name,\" it's the email that will be used.\n4. In \"password,\" you will enter the password generated from the Gmail application registration.\n\nAdd in `config/environments/development.rb`:\n\n```\nconfig.action_mailer.delivery_method = :smtp\nconfig.action_mailer.smtp_settings = {\n  address: \"smtp.gmail.com\",\n  port: 587,\n  domain: \"gmail.com\",\n  authentication: \"plain\",\n  enable_starttls_auto: true,\n  user_name: Rails.application.credentials.gmail_username,\n  password: Rails.application.credentials.gmail_password\n}\n```\n\n## 3. UsersController Implementation  \nIn our Controller, this is where the methods responsible for handling requests and implementing the logic for sending emails are located.\nChange `app/controllers/users_controller.rb`:\n\n```\nclass UsersController \u003c ApplicationController\n  def new\n    @user = User.new\n  end\n\n  def create\n    @user = User.new(user_params)\n    if @user.save\n      UserMailer.verification_email(@user).deliver_now\n      redirect_to verify_user_path(@user), notice: \"Code sent to your email.\"\n    else\n      render :new, status: :unprocessable_entity, notice: \"Try again\"\n    end\n  end\n\n  def verify\n    @user = User.find(params[:id])\n  end\n\n  def confirm_verification\n    @user = User.find(params[:id])\n    if @user.verification_code == params[:verification_code]\n      @user.update(verified: true, verification_code: nil)\n      redirect_to new_session_path, notice: \"Account verified! Log in.\"\n    else\n      flash.now[:alert] = \"Code invalid!\"\n      render :verify, status: :unprocessable_entity\n    end\n  end\n\n  def resend_verification_code\n    @user = User.find(params[:id])\n    @user.update(verification_code: rand(100000..999999).to_s)\n    UserMailer.verification_email(@user).deliver_now\n\n    redirect_to verify_user_path(@user), notice: \"New code sent to your email.\"\n  end\n\n  def show\n    @user = User.find(params[:id])\n  end\n\n  private\n\n  def user_params\n    params.require(:user).permit(:name, :email, :password, :password_confirmation)\n  end\nend\n```\n\n## 4. Create the Email Verification View.\nThis will be our basic view where we can enter the code we receive in the email.\nCreate `app/views/users/verify.html.erb`:\n\n```\n\u003cdiv class=\"max-w-md mx-auto mt-10 p-6 bg-white shadow-lg rounded-lg\"\u003e\n  \u003ch1 class=\"text-2xl font-bold mb-4\"\u003eVerificação de Conta\u003c/h1\u003e\n\n  \u003cp class=\"mb-4\"\u003eA verification code has been sent to your email.\u003c/p\u003e\n\n  \u003c%= form_with url: confirm_verification_user_path(@user), local: true, class: \"space-y-4\" do |form| %\u003e\n    \u003cdiv\u003e\n      \u003c%= form.label :verification_code, \"Enter the Code\", class: \"block text-sm font-medium text-gray-700\" %\u003e\n      \u003c%= form.text_field :verification_code, class: \"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" %\u003e\n    \u003c/div\u003e\n\n    \u003cdiv\u003e\n      \u003c%= form.submit \"Verify Account\", class: \"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\" %\u003e\n    \u003c/div\u003e\n  \u003c% end %\u003e\n  \u003cp id=\"resend-info\"\u003eYou can resend the code at \u003cspan id=\"timer\"\u003e30\u003c/span\u003e seconds.\u003c/p\u003e\n  \u003c%= button_to \"Resend Code\", resend_verification_code_user_path(@user), method: :post, id: \"resend-button\", disabled: true %\u003e\n\u003c/div\u003e\n\n\u003cscript\u003e\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    let timer = 30;\n    let button = document.getElementById(\"resend-button\");\n    let timerText = document.getElementById(\"timer\");\n    \n    let countdown = setInterval(function() {\n      timer--;\n      timerText.textContent = timer;\n      \n      if (timer \u003c= 0) {\n        clearInterval(countdown);\n        button.disabled = false;\n        document.getElementById(\"resend-info\").textContent = \"Didn't receive the code? Resend now.\";\n      }\n    }, 1000);\n  });\n\u003c/script\u003e\n```\n\n## 5. Routes configuration\nLastly, the configuration of our routes.\n\n```\nresources :users, only: [:new, :create, :show] do\n  member do\n    get :verify\n    post :confirm_verification\n    post :resend_verification_code\n  end\nend\n```\n\n## Conclusion\n\nAnd that's it, now you can send real emails. If it's just for local testing, Gmail works well. For production, SendGrid or Mailgun are more recommended. Rails is capable of doing countless things with numerous possibilities, and email sending is one of them with relative ease. I hope this article helps those who need it, and if you find something wrong or have a suggestion for improvement, feel free to leave it in the comments so we can discuss it.\n\nRepository in my Github: [Rails-Verification-Email](https://github.com/pedrosrc/Rails-Verification-Email)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrosrc%2Frails-verification-email","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrosrc%2Frails-verification-email","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrosrc%2Frails-verification-email/lists"}