![見出し画像](https://assets.st-note.com/production/uploads/images/17893391/rectangle_large_type_2_d041b7374132f91048b48a7dfeb50bbd.jpeg?width=1200)
railsチュートリアル魔改造編 第17章 新規登録メール魔改造
第17章 新規登録メール魔改造編
新規登録メールを魔改造していきます。
いつものようにトピックブランチを作成します。
git checkout -b rails-makaizou-17
17.1 新規登録メール魔改造
新規登録後に表示される文字列を魔改造します。
まず、新規登録フォームで登録をクリック処理はどこを通るのでしょうか?
リスト17.01: 新規登録フォーム
/sample_app/app/views/users/new.html.erb
----------------------------
<%#
# /signup で呼ばれるアクション
# app/views/users/new.html.erbへ
def new
#ユーザーを新規に作成する
@user = User.new
end
%>
<%# 見出しを新規登録にする %>
<% provide(:title, '新規登録') %>
<%# 見出しを新規登録にする %>
<h1>新規登録</h1>
<%# Bootstrapの機能で、12列に何を割り当てるか決める %>
<div class="row">
<%# 空白3-入力スペース6-空白3の構成にする %>
<div class="col-md-6 col-md-offset-3">
<%# フォームを作成し、@userにデータを入れていく %>
<%= form_for(@user) do |f| %>
<%# エラー文を出力する %>
<%= render 'shared/error_messages', object: f.object %>
<%# 名前 %>
<%= f.label :name, "名前" %>
<%= f.text_field :name, class: 'form-control' %>
<%# メールアドレス %>
<%= f.label :email, "メールアドレス" %>
<%= f.email_field :email, class: 'form-control' %>
<%# パスワード %>
<%= f.label :password, "パスワード" %>
<%= f.password_field :password, class: 'form-control' %>
<%# パスワード(再入力) %>
<%= f.label :password_confirmation, "パスワード(再入力)" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%# パスワード(再入力) %>
<%= f.submit "魔改造アカウントを作成する", class: "btn btn-danger" %>
<% end %>
</div>
</div>
以下の記事を参考にしました。
https://qiita.com/kitsunecat/items/1d4d07ba590c9f44e2cd
送信ボタンをクリックすると、どこに飛ぶのかパッと見ではわかるようになっていません。
答えは、form_forの仕様でusersコントローラのcreateを呼ぶようになっています。
/sample_app/app/controllers/users_controller.rb
のcreateアクションを見てみます。
@user = User.new(user_params)
という行の、user_paramsとはいったいなんでしょう?
同じファイルのprivateのところに、定義があります。
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
paramsは前ページから送信されたデータが入っている特殊なテーブルです。
require、permitは何をしているのでしょう?
requireとpermitで、paramsから不要なパラメータを取り除き、必要なパラメータに絞り込むためのメソッドです。
requireメソッドで受け取るパラメータ群を、permitメソッドで利用可能なパラメータ名を指定します。
form_forでは@userを指定しました。
そのあと、labelは:nameと:emailと:passwordと:password_confirmationを入力しました。
paramsから、:userの:name,:email,:password,:password_confirmationを抽出するということですね。
ちなみにrequireは必要、permitは許可という意味です。
railsチュートリアル7.3.2章で習ったStrong Parameterというやつです。
user_paramsメソッドを使うことで、User.new(name: "~",email: "~",password: "~", password_confirmation:"~")と同じになります。
そして、以下の行がある。
@user.send_activation_email
send_activation_emailはどこか?
app/models/user.rbに、メソッドの定義がある。
UserMailer.account_activation(self).deliver_now
によって、メールが送信されていく。
deliver_nowは、今すぐ送信する時に使用する
app/mailers/user_mailer.rb
に、account_activationの定義がある。
このメソッドによって、送り先と件名が決定する。
ちなみにrailsチュートリアル11章で、アカウントの有効化を実装しました。
以下でプレビューが表示されたかと思います。
URLごにょごにょ/rails/mailers/user_mailer/account_activation
URLごにょごにょ/rails/mailers/user_mailer/account_activation.txt
それらの内容は、下記で変更できる
app/views/user_mailer/account_activation.html.erb
app/views/user_mailer/account_activation.text.erb
それぞれを確認しながら、メールの内容を魔改造します。
注意として、textのほうはURLがクリックできないので、それを考慮して文章を考える必要があるかも。
edit_account_activation_urlは、以下の箇所で作成される
/sample_app/config/routes.rb
resources :account_activations, only: [:edit]
そして、Userのインスタンスであるactivation_tokenは、
/sample_app/app/models/user.rb
に定義がある。
それは、インスタンスメソッドであるcreate_activation_digestを呼び出すことで、ダイジェストと一緒に作成される
activation_tokenは、クラスメソッドであるnew_tokenで作成する
このメソッドはSecureRandom.urlsafe_base64でランダムに作成したトークンを返すだけのシンプルなメソッドである。
クラスメソッドのdigestは、引数にトークンを渡すことで、ハッシュ値を返す
じゃあ、create_activation_digestは、どこで呼び出しているか?
実は、/sample_app/app/models/user.rbのbefore_createを使って、データベースへの登録前でのみ呼び出されるようになっている(before_saveはデータベースへの登録と更新で呼び出される)
ここでrails testをすると、REDになるはず
ログ
----------------------------
ec2-user:~/environment/sample_app (rails-makaizou-17) $ rails test
Running via Spring preloader in process 9822
Started with run options --seed 52825
FAIL["test_account_activation", UserMailerTest, 1.8401885599996604]
test_account_activation#UserMailerTest (1.84s)
Expected /Michael\ Example/ to match # encoding: US-ASCII
"\r\n----==_mimepart_5e1b3047f06ec_265e12d19a4780d\r\nContent-Type: text/plain;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: base64\r\n\r\nTWljaGFlbCBFeGFtcGxl44GV44KT44CB44GT44KT44Gr44Gh44Gv77yBDQoN\r\nCuS7peS4i+OBrlVSTOOCkumWi+OBj+OBqOOAgeOCouOCq+OCpuODs+ODiOOB\r\njOacieWKueOBq+OBquOCiuOBvuOBmeOAgg0KDQpodHRwOi8vZXhhbXBsZS5j\r\nb20vYWNjb3VudF9hY3RpdmF0aW9ucy9Pam8zUHloVkYyOWQ5SXg4VUgyekZ3\r\nL2VkaXQ/ZW1haWw9bWljaGFlbCU0MGV4YW1wbGUuY29tDQo=\r\n\r\n----==_mimepart_5e1b3047f06ec_265e12d19a4780d\r\nContent-Type: text/html;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: base64\r\n\r\nPCFET0NUWVBFIGh0bWw+DQo8aHRtbD4NCiAgPGhlYWQ+DQogICAgPG1ldGEg\r\naHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7\r\nIGNoYXJzZXQ9dXRmLTgiIC8+DQogICAgPHN0eWxlPg0KICAgICAgLyogRW1h\r\naWwgc3R5bGVzIG5lZWQgdG8gYmUgaW5saW5lICovDQogICAgPC9zdHlsZT4N\r\nCiAgPC9oZWFkPg0KDQogIDxib2R5Pg0KICAgIDxwPk1pY2hhZWwgRXhhbXBs\r\nZeOBleOCk+OAgeOBk+OCk+OBq+OBoeOBr++8gTwvcD4NCg0KPHA+DQrku6Xk\r\nuIvjga5VUkzjgpLjgq/jg6rjg4Pjgq/jgZnjgovjgajjgIHjgqLjgqvjgqbj\r\ng7Pjg4jjgYzmnInlirnjgavjgarjgorjgb7jgZnjgIINCjwvcD4NCg0KPGEg\r\naHJlZj0iaHR0cDovL2V4YW1wbGUuY29tL2FjY291bnRfYWN0aXZhdGlvbnMv\r\nT2pvM1B5aFZGMjlkOUl4OFVIMnpGdy9lZGl0P2VtYWlsPW1pY2hhZWwlNDBl\r\neGFtcGxlLmNvbSI+44Ki44Kr44Km44Oz44OI44KS5pyJ5Yq544Gr44GZ44KL\r\nPC9hPg0KICA8L2JvZHk+DQo8L2h0bWw+DQo=\r\n\r\n----==_mimepart_5e1b3047f06ec_265e12d19a4780d--\r\n".
test/mailers/user_mailer_test.rb:12:in `block in <class:UserMailerTest>'
74/74: [=====================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.76447s
74 tests, 425 assertions, 1 failures, 0 errors, 0 skips
----------------------------
test/mailers/user_mailer_test.rb
を見ても、特に問題になるようには見えない
https://teratail.com/questions/188866
にて、日本語が混じるとエンコード周りで駄目になるとのこと。
gem 'mail-iso-2022-jp' を入れると解決するようだが、今回は見送り。
ちなみに以下の3行全てで引っかかる。
#assert_match user.name, mail.body.encoded
#assert_match user.activation_token, mail.body.encoded
#assert_match CGI.escape(user.email), mail.body.encoded
ので、コメントアウトにした。
17.2 メール送信後メッセージ魔改造
/sample_app/app/controllers/users_controller.rbのcreateメソッドにそのメッセージがあるので、書き換える
ここでrails testをすると、REDになるはずである。
ログ
----------------------------
ec2-user:~/environment/sample_app (rails-makaizou-17) $ rails test
Running via Spring preloader in process 9282
Started with run options --seed 9619
FAIL["test_account_activation", UserMailerTest, 2.290641062998475]
test_account_activation#UserMailerTest (2.29s)
Expected: "Account activation"
Actual: "railsチュートリアル魔改造へようこそ!"
test/mailers/user_mailer_test.rb:9:in `block in <class:UserMailerTest>'
74/74: [====================================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.61194s
74 tests, 422 assertions, 1 failures, 0 errors, 0 skips
----------------------------
原因は下記
/sample_app/test/mailers/user_mailer_test.rb
:
assert_equal "Account activation", mail.subject
:
これはコメントアウトしておく。件名は変わる可能性があるため。
17.3 アカウント有効後メッセージ魔改造
アカウント有効後に表示されるメッセージを魔改造します。
URLを辿ると、
/sample_app/app/controllers/account_activations_controller.rb
のeditが呼び出される
emailは、urlに乗っけられてる
find_byは、1件のみ取得する
user.activatedは、
db/migrate/〇〇_add_activation_to_users.rb
に定義がある
authenticated?は、
/sample_app/app/models/user.rb
に定義がある
user.activateは、
/sample_app/app/models/user.rb
に定義がある
そこにあるupdate_columnsはrailsで普通に使える関数
テーブルの値を複数更新する時とかに使う
ちなみにupdate_columnsとupdate_columnの違いは下記
https://qiita.com/lemtosh469/items/371544fa4fd3c333adf1
1つだけの更新をするか、複数更新するかの違い
log_inは、
/sample_app/app/helpers/sessions_helper.rb
に定義がある
ここで、ようやく有効化に成功したときと失敗したときのメッセージが表示される処理にたどり着く。長かった・・・
ここを魔改造する。
17.4 最後に
保存する
rails test
git add -A
git status
ログ
----------------------------
ec2-user:~/environment/sample_app (rails-makaizou-17) $ git status
On branch rails-makaizou-17
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: app/controllers/account_activations_controller.rb
modified: app/controllers/users_controller.rb
modified: app/helpers/sessions_helper.rb
modified: app/mailers/user_mailer.rb
modified: app/models/user.rb
modified: app/views/static_pages/home.html.erb
modified: app/views/user_mailer/account_activation.html.erb
modified: app/views/user_mailer/account_activation.text.erb
modified: config/routes.rb
modified: test/mailers/user_mailer_test.rb
----------------------------
10ファイル修正したことを確認
git commit -m "add 17"
git checkout master
修正前ファイルをブログ用に保存しておく
git merge rails-makaizou-17
ログ
----------------------------
ec2-user:~/environment/sample_app (master) $ git merge rails-makaizou-17
Updating 6ea4cdb..f8c21a9
Fast-forward
.../account_activations_controller.rb | 25 +++++++++++-
app/controllers/users_controller.rb | 23 ++++++++++-
app/helpers/sessions_helper.rb | 2 +-
app/mailers/user_mailer.rb | 9 ++++-
app/models/user.rb | 39 ++++++++++++++++++-
app/views/static_pages/home.html.erb | 7 ++++
.../user_mailer/account_activation.html.erb | 10 ++---
.../user_mailer/account_activation.text.erb | 4 +-
config/routes.rb | 6 +++
test/mailers/user_mailer_test.rb | 8 ++--
10 files changed, 114 insertions(+), 19 deletions(-)
----------------------------
修正後ファイルをブログ用に保存しておく
git push origin master
そしてherokuの操作
source <(curl -sL https://cdn.learnenough.com/heroku_install)
差分の画像を保存したいので、
railsチュートリアル14章のデータベースをリセットするためにいったん切り替える。絶対にpushしないようにする。
git remote set-url heroku https://git.heroku.com/jun-killer-rails14.git
heroku maintenance:on
heroku pg:reset DATABASE
jun-killer-rails14
heroku run rails db:migrate
heroku run rails db:seed
heroku restart
heroku maintenance:off
そして、railsチュートリアル魔改造17章用にまた切り替える
こちらは必ずpushする
git remote set-url heroku https://git.heroku.com/jun-killer-makaizou.git
heroku maintenance:on
git push heroku master
heroku pg:reset DATABASE
jun-killer-makaizou
heroku run rails db:migrate
heroku run rails db:seed
heroku restart
heroku maintenance:off
https://jun-killer-rails14.herokuapp.com/
https://jun-killer-makaizou.herokuapp.com/
スクショを取るのは
・有効化前のメッセージ
・メールの内容
・有効化に失敗したとき
・有効化に成功したとき
17.4.1 修正後
リスト17.02:
app/controllers/account_activations_controller.rb
----------------------------
class AccountActivationsController < ApplicationController
#メールアドレスからURLを辿ったあとに呼び出される
def edit
#メールアドレスを元に、テーブルから1件だけユーザー情報を取得する
#params[:email]とparams[:id]は、本文のerb(viewのなんとかmailer)で作成される
user = User.find_by(email: params[:email])
#ユーザーが存在しており、有効化はまだ済んでおらず、ダイジェストとトークンが一致するとき
#activatedはdb/migrate/〇〇_add_activation_to_users.rbに定義がある
#authenticated?は/sample_app/app/models/user.rbに定義がある
if user && !user.activated? && user.authenticated?(:activation, params[:id])
#ユーザーを有効化する
#app/models/user.rbに定義がある
user.activate
#ユーザーをログイン状態にする
#app/helpers/sessions_helper.rbに定義がある
log_in user
#有効化に成功したときのメッセージを出力する
flash[:success] = "railsチュートリアル魔改造へようこそ!"
#ユーザーページへ
redirect_to user
#認証になんらかの理由で失敗したとき
else
#有効化に失敗したときのメッセージを出力する
flash[:danger] = "申し訳ありません。認証に失敗しました。パスワードの変更をお願いします。"
#トップページへ
redirect_to root_url
end
end
end
リスト17.03:
app/controllers/users_controller.rb
----------------------------
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
:following, :followers]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
@users = User.where(activated: true).paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
@microposts = @user.microposts.paginate(page: params[:page])
end
# /signup で呼ばれるアクション
# app/views/users/new.html.erbへ
def new
#ユーザーを新規に作成する
@user = User.new
end
# app/views/users/new.html.erbでform_forによって送信を押した後に呼ばれる
def create
#入力フォームに入力された値でユーザーデータを作成する
#user_paramsは同ファイルのprivateに定義がある
#user_paramsはStrongParameterが返ってくる
@user = User.new(user_params)
#セーブに成功した?
if @user.save
#メールを送信する
#send_activation_emailの定義はapp/models/user.rbにある
#メールの内容は以下で編集できる
#app/views/user_mailer/account_activation.html.erb
#app/views/user_mailer/account_activation.text.erb
@user.send_activation_email
#メールを送信したことを通知する
flash[:info] = @user.email+"にメールを送信しました。お手数ですが、承認をお願いします。"
#トップページに移行する
redirect_to root_url
#セーブに失敗した?
else
#再度入力をお願いする
#エラー文は自動的に出るようになってる
render 'new'
end
end
def edit
end
def update
if @user.update_attributes(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
def following
@title = "Following"
@user = User.find(params[:id])
@users = @user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
@title = "Followers"
@user = User.find(params[:id])
@users = @user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
#paramsの中身を:userの:name,:email,:password,:password_confirmationのみにして返す
#StrongParameterというやつ
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# beforeアクション
# 正しいユーザーかどうか確認
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
# 管理者かどうか確認
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
リスト17.04:
app/helpers/sessions_helper.rb
----------------------------
module SessionsHelper
# 渡されたユーザーをログイン状態にする
def log_in(user)
session[:user_id] = user.id
end
# ユーザーのセッションを永続的にする
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
# 渡されたユーザーがログイン済みユーザーであればtrueを返す
def current_user?(user)
user == current_user
end
# 現在ログイン中のユーザーを返す (いる場合)
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(:remember, cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# ユーザーがログインしていればtrue、その他ならfalseを返す
def logged_in?
!current_user.nil?
end
# 永続的セッションを破棄する
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
# 現在のユーザーをログアウトする
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
# 記憶したURL (もしくはデフォルト値) にリダイレクト
def redirect_back_or(default)
redirect_to(session[:forwarding_url] || default)
session.delete(:forwarding_url)
end
# アクセスしようとしたURLを覚えておく
def store_location
session[:forwarding_url] = request.original_url if request.get?
end
end
リスト17.05:
app/mailers/user_mailer.rb
----------------------------
class UserMailer < ApplicationMailer
# アカウント有効化用初期設定
#app/models/user.rbから呼ばれる
def account_activation(user)
#ユーザー情報を取得する(意味あるのか?)
@user = user
#ユーザーのメールアドレスに対して、件名を設定する
#メールの内容は以下で編集できる
#app/views/user_mailer/account_activation.html.erb
#app/views/user_mailer/account_activation.text.erb
mail to: user.email, subject: "railsチュートリアル魔改造へようこそ!"
end
def password_reset(user)
@user = user
mail to: user.email, subject: "Password reset"
end
end
リスト17.06:
app/models/user.rb
----------------------------
class User < ApplicationRecord
has_many :microposts, dependent: :destroy
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
#トークンを作成
#リメンバーミー用トークン
attr_accessor :remember_token
#承認用トークン
attr_accessor :activation_token
#パスワードリセット用トークン
attr_accessor :reset_token
#データベースへ登録前と更新前のどちらかでメールアドレスを小文字にする
before_save :downcase_email
#データベースへ登録前にトークンとダイジェストを作成する
before_create :create_activation_digest
#名前を表す
#空白NG
#最大50文字
validates :name, presence: true, length: { maximum: 50 }
#emailを表す
#正規表現用の文字列をVALID_EMAIL_REGEXへ
#空白NG
#最大255文字
#フォーマットはVALID_EMAIL_REGEXに従う
#一意であること
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true,
length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
# 渡された文字列のハッシュ値を返す
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# ランダムなトークンを返す
def User.new_token
SecureRandom.urlsafe_base64
end
# 永続セッションのためにユーザーをデータベースに記憶する
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# トークンがダイジェストと一致したらtrueを返す
#app/controllers/account_activations_controller.rbのeditアクションで呼ばれる
def authenticated?(attribute, token)
#メタプログラミングでactivation_digestインスタンスを取得する
digest = send("#{attribute}_digest")
#たぶんないが、念のためnilでないことを確認する
return false if digest.nil?
#インスタンスのダイジェストとトークンから生成したダイジェストが
#一致すればtrue
#一致しなければfalse
BCrypt::Password.new(digest).is_password?(token)
end
# ユーザーのログイン情報を破棄する
def forget
update_attribute(:remember_digest, nil)
end
# アカウントを有効にする
def activate
#有効化状態と、有効化日時を更新
update_columns(activated: true, activated_at: Time.zone.now)
end
# 有効化用のメールを送信する
#app/controllers/users_controller.rbから呼ばれる
def send_activation_email
#メイラーを使ってメールを今すぐに送信する
#account_activationの定義はapp/mailers/user_mailer.rbにある
UserMailer.account_activation(self).deliver_now
end
# パスワード再設定の属性を設定する
def create_reset_digest
self.reset_token = User.new_token
update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
end
# パスワード再設定のメールを送信する
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# パスワード再設定の期限が切れている場合はtrueを返す
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
# ユーザーのステータスフィードを返す
def feed
following_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
Micropost.where("user_id IN (#{following_ids})
OR user_id = :user_id", user_id: id)
end
# ユーザーをフォローする
def follow(other_user)
following << other_user
end
# ユーザーをフォロー解除する
def unfollow(other_user)
active_relationships.find_by(followed_id: other_user.id).destroy
end
# 現在のユーザーがフォローしてたらtrueを返す
def following?(other_user)
following.include?(other_user)
end
private
# メールアドレスをすべて小文字にする
def downcase_email
self.email = email.downcase
end
# 有効化トークンとダイジェストを作成および代入する
def create_activation_digest
#有効化用トークンを作成する
self.activation_token = User.new_token
#トークンを元にダイジェストを作成する
self.activation_digest = User.digest(activation_token)
end
end
リスト17.07:
app/views/static_pages/home.html.erb
----------------------------
<%# ログイン中? %>
<% if logged_in? %>
<%# Bootstrapでくくる準備 %>
<div class="row">
<%# 12分割して左側幅4つ分を使用する %>
<aside class="col-md-4">
<%# ユーザーの情報を表示する %>
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<%# ステータスを表示する %>
<section class="stats">
<%= render 'shared/stats' %>
</section>
<%# マイクロポストフォームを表示する %>
<section class="micropost_form">
<%= render 'shared/micropost_form' %>
</section>
</aside>
<%# 12分割して右側幅8つ分を使用する %>
<div class="col-md-8">
<%# 他の人のマイクロポストを表示する %>
<h3>Micropost Feed</h3>
<%= render 'shared/feed' %>
</div>
</div>
<%# ログインしていない? %>
<% else %>
<%# タイトル %>
<div class="center">
<%= image_tag("title.jpg", alt: "title") %>
<h1>railsチュートリアル<br>魔改造</h1>
<%# サブタイトル %>
<h2>
全ページ……魔改造してやる!<br>このサイトから……一ページ残らず!
</h2>
<%# 新規登録ボタンを赤色(danger)にする %>
<%= link_to "新規登録", signup_path, class: "btn btn-lg btn-danger signup " %>
</div>
<% end %>
リスト17.08:
app/views/user_mailer/account_activation.html.erb
----------------------------
<p><%= @user.name %> さん、こんにちは!</p>
<p>
以下のURLをクリックすると、アカウントが有効になります。
</p>
<%# edit_account_activation_urlは、config/routes.rbで作成され、そのURLに色々とくっつける %>
<%= link_to "アカウントを有効にする", edit_account_activation_url(@user.activation_token,
email: @user.email) %>
リスト17.09:
app/views/user_mailer/account_activation.text.erb
----------------------------
<%= @user.name %> さん、こんにちは!
以下のURLを開くと、アカウントが有効になります。
<%= edit_account_activation_url(@user.activation_token, email: @user.email) %>
リスト17.10:
config/routes.rb
----------------------------
Rails.application.routes.draw do
# ルートページ
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
# 新規登録ページは、/signup
# app/controllers/users_controller.rbのnewアクションへ
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users do
member do
get :following, :followers
end
end
#アカウント有効化用ルーティングをeditのみ作成する
#edit_account_activation_urlで、以下が実行される
#app/controllers/users_controller.rbのeditアクション
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :microposts, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
end
リスト17.11:
test/mailers/user_mailer_test.rb
----------------------------
class UserMailer < ApplicationMailer
# アカウント有効化用初期設定
#app/models/user.rbから呼ばれる
def account_activation(user)
#ユーザー情報を取得する(意味あるのか?)
@user = user
#ユーザーのメールアドレスに対して、件名を設定する
#メールの内容は以下で編集できる
#app/views/user_mailer/account_activation.html.erb
#app/views/user_mailer/account_activation.text.erb
mail to: user.email, subject: "railsチュートリアル魔改造へようこそ!"
end
def password_reset(user)
@user = user
mail to: user.email, subject: "Password reset"
end
end
17.4.2 本章のまとめ
新規登録後に表示されるメッセージを変えることができた
メールの内容を変更することができた。
有効化成功時と有効化失敗時のメッセージを変えることができた。
フォームからどのアクションが呼ばれるのか分かった。
paramsのrequireメソッドとpermitメソッドは、不要なパラメータを取り除き、必要なパラメータに絞り込むためのメソッドであることが分かった。
StrongParameterがなんのためにあるのか分かった。
deliver_nowについて意味を理解した
エンコードの関係で、メールの本文に日本語があると、railsチュートリアルのminitestが失敗することが分かった。対策方法までは踏み込まなかったが、gemを追加すると直るらしい。
ダイジェストとトークンの違いが分かった。ダイジェストは生成したトークンを元に作成されたあとにデータベースに保存されてて、トークンはURLとかに埋め込まれ、それを変換してデータベース上のダイジェストと比較していることが分かった。
before_createとbefore_saveがいつ呼ばれるのか分かった。
user.activatedとuser.authenticatedとuser.activateが紛らわしいなと思った。コメントで補足するのが吉と判断。
修正前
修正後
この記事が気に入ったらサポートをしてみませんか?