Userのメイラーを追加します。
このメイラーはUsersコントローラのcreateアクションで有効化リンクをメール送信するために使います。
ubuntu:~/environment/my_app (account-activation) $ rails generate mailer UserMailer account_activation password_reset
Running via Spring preloader in process 12921
create app/mailers/user_mailer.rb
invoke erb
create app/views/user_mailer
create app/views/user_mailer/account_activation.text.erb
create app/views/user_mailer/account_activation.html.erb
create app/views/user_mailer/password_reset.text.erb
create app/views/user_mailer/password_reset.html.erb
invoke test_unit
create test/mailers/user_mailer_test.rb
create test/mailers/previews/user_mailer_preview.rb
###app/views/user_mailer/account_activation.text.erb
app/views/user_mailer/account_activation.text.erb
###app/views/user_mailer/account_activation.html.erb
app/views/user_mailer/account_activation.html.erb
<h1>Sample App</h1>
<p>Hi <%= @user.name %>,</p>
<p>
Welcome to the Sample App! Click on the link below to activate your account:
</p>
<%= link_to "Activate", edit_account_activation_url(@user.activation_token,
email: @user.email) %>
###app/mailers/application_mailer.rb
app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
###app/mailers/user_mailer.rb
app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
def account_activation(user)
@user = user
# インスタンス引数
mail to: user.email, subject: "Account activation"
#
end
def account_activation
@greeting = "こんにちは!"
mail to: "to@example.org"
end
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.user_mailer.password_reset.subject
#
def password_reset
@greeting = "こんにちは!"
mail to: "to@example.org"
end
end
###config/environments/development.rb
config/environments/development.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
host = 'example.com' # ここをコピペすると失敗します。自分の環境のホストに変えてください。
# クラウドIDEの場合は以下をお使いください
config.action_mailer.default_url_options = { host: host, protocol: 'https' }
# localhostで開発している場合は以下をお使いください
# config.action_mailer.default_url_options = { host: host, protocol: 'http' }
config.action_mailer.perform_caching = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
# Cloud9 への接続を許可する
config.hosts.clear
end
###test/mailers/previews/user_mailer_preview.rb
test/mailers/previews/user_mailer_preview.rb
# Preview all emails at http://localhost:3000/rails/mailers/user_mailer
class UserMailerPreview < ActionMailer::Preview
# Preview this email at http://localhost:3000/rails/mailers/user_mailer/account_activation
def account_activation
# アカウント作成をされたら自分にメールが送信されるためのメソッド
user = User.first
# db最初のユーザーを代入
user.activation_token = User.new_token
# 最初のユーザーに新しいトークンを生成
UserMailer.account_activation(user)
# 有効化のためにメールを送信する
end
# Preview this email at http://localhost:3000/rails/mailers/user_mailer/password_reset
def password_reset
UserMailer.password_reset
end
end
###test/mailers/user_mailer_test.rb
test/mailers/user_mailer_test.rb
require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test "account_activation" do
# 登録時送信メールのテスト
user = users(:michael)
# テストユーザー
user.activation_token = User.new_token
# 新しいトークンを作成 有効化トークンに代入
mail = UserMailer.account_activation(user)
# 登録用のメールを送信する
assert_equal "Account activation", mail.subject
# 内容があっているか確認
assert_equal [user.email], mail.to
assert_equal ["noreply@example.com"], mail.from
assert_match user.name, mail.body.encoded
assert_match user.activation_token, mail.body.encoded
assert_match CGI.escape(user.email), mail.body.encoded
end
end
###config/environments/test.rb
config/environments/test.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
config.cache_classes = false
config.action_view.cache_template_loading = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
}
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.cache_store = :null_store
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Store uploaded files on the local file system in a temporary directory.
config.active_storage.service = :test
config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
config.action_mailer.default_url_options = { host: 'example.com' }
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
end
###app/controllers/users_controller.rb
app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
@users = User.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
UserMailer.account_activation(@user).deliver_now
# deliver_now
# メール自身が送信対象であることをdeliver_nowやdeliver_laterに伝えます
flash[:info] = "メールをチェックしてアカウントを有効にしてください。"
redirect_to root_url
# 自動的に移動する
else
render 'new'
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# 正しいユーザーかどうか確認
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless @user == current_user
end
# 管理者かどうか確認
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end