Rails チュートリアル読んでみた(その3)
第9章 発展的なログイン機構
- SecureRandom.urlsafe_base64 : 英文字の小文字・大文字、英数字、"-"、“_” のいづれかの文字(64文字)を使って長さ22のランダムな文字列を作成するメソッド。記憶トークン(永続的cookiesの照合に用いられる為にPC側で作られ、秘匿管理されるパスワード)の作成などに用いられる
- 時刻や数値を返すメソッド
-
数字.years.from_now: 今から数年後を返す。 -
数字.weeks.ago: 今から数週間前を返す。 -
数字.kilobytes: 数字*210(バイト数)を返す。 -
数字.megabytes: 数字*220(バイト数)を返す。
- cookies[:シンボル名] = { value: 値, expires: 期限日 } : 有効期限付きの永続的cookieを作成するメソッド。 expires: 期限日 は省略可であり、その場合の期限日は20年後に設定される
- cookies.permanent[:シンボル名] = 値 : 20年後まで有効な永続的cookieを作成するメソッド
- cookies.permanent.signed[:シンボル名] = 値 : 20年後まで有効な署名付きcookie(値を暗号化した永続的cookie)を作成するメソッド。 cookies.signed[:シンボル名] で元の値を取り出す事が出来る
- BCrypt::Password.new(暗号化された文字列).is_password?(文字列) : 暗号化された文字列と文字列が一致するかを比較するメソッド。secure_password内で使われている
- 評価式 ? 評価式がtrueの時にする処理 : 評価式がfalseの時にする処理 : 三項演算子
- 統合テスト用のヘルパーを作る時は ActionDispatch::IntegrationTest クラス内に実装する。見つけやすいようにテスト用ヘルパーのコード test/test_helper.rb に続けて記述
- テスト内でcookiesを呼び出す時は cookies[:シンボル名] ではなく cookies[‘シンボル名’] を使う。テスト内ではcookiesメソッドにシンボルが使えないらしい(多分、ブラウザに保存されたcookiesのキーが文字列だからか)?文字列だと呼び出し可
- assigns(:インスタンス変数名) : コントローラー内で定義したインスタンス変数をテスト内に呼び出すテストメソッド。インスタンス変数がハッシュの場合、直後に .シンボル名 を記述すれば、その値を取得可
- テストが通っているか怪しい箇所に例外処理 raise を書き、テストをしてみる。この時、テストが通ったら raise を書いた箇所をテストが想定できていないと言うことが分かる
- % heroku maintenance:on : 本番環境にメンテナンスページを表示し、ページへのアクセスを禁止する。 % heroku maintenance:off で戻す
第10章 ユーザーの更新・表示・削除
- <a href=“リンク先URL” target="_blank">表示テキスト</a> : リンク先を開く際にブラウザ上で新規タブまたは、新規ウィンドウ上で開いてくれる
- レコードオブジェクト.new_record? : レコードオブジェクトの内容がテーブルに無かったら true 既に存在したら false を返すメソッド。Railsはform_for()が受け取ったレコードオブジェクトにこのメソッドを使い、テーブルに既にある場合はPATCHリクエスト、無い場合はPOSTリクエストをそれぞれ自動生成している
- 新規タブまたは、新規ウィンドウでリンク先を開く(aタグで target="_blank" を使用する)と、リンク先のURLをローカル側で別のURLに変更 window.opener.location = 別のURL 出来るため、フィッシングサイトの温床となってしまう。なのでaタグに rel=“noopener” を設定する1
- モデルオブジェクト.reload : モデルオブジェクトを呼び直す。この時、データベースに変更があった場合、モデルオブジェクトの中身が更新される
- before_action :メソッド名, only: [:アクション名, :アクション2名, ... ] : 特定のアクションが動く直前に働くメソッド。onlyオプションにハッシュでアクション名を渡して設定する
- request.original_url : 現在のリクエスト先のURLを返すメソッド。コントローラー内に記述。また、リクエストの形式を調べる時は request.形式名? を記述
- データベースにサンブルアカウントを大量に生成する方法
1. Gemfileで faker gem(実際に居そうなユーザ名を作成してくれるgem)をインストール。
2. db/seeds.rb に以下のようなサンプルアカウントを大量に生成する為のコードを記述。
User.create!(name: "Example User", email: "example@railstutorial.org", password: "foobar", password_confirmation: "foobar") 99.times do |n| name = Faker::Name.name email = "example-#{n+1}@railstutorial.org" password = "password" User.create!(name: name, email: email, password: password, password_confirmation: password) end
3. % rails db:seed でコードを実行。この時、エラーが出るようなら % rails db:migrate:reset でレコードを全て削除してから実行するか、Railsサーバを実行中 % rails server なら、それを止めてから実行すると良いかも。
4*. Faker::Lorem.sentence(単語数) : 指定された単語数分の投稿文っぽい文章を返すメソッドが使えるようになる2。
- 表示されるページをページング(大量のレコードを一定数毎に分けて複数のページとして表示)する方法
1. will_paginate gemと bootstrap-will_paginate gemをGemfileでインストール。
2. モデルから paginate() メソッドを使って、レコードオブジェクトに一定数(デフォルトでは30個)のレコードを一つの要素としたデータ配列を保持。コントローラ内で以下のように記述。
︙ def アクション名 @レコードオブジェクト名 = モデル.paginate(page: params[:page]) end ︙
3. view内でページングする領域を以下のように記述。
<%= will_paginate @レコードオブジェクト名 %> <% @レコードオブジェクト名.each do |イテレーター| %> レコード一つに対して表示したい内容 <% end %> <%= will_paginate %>
また <%= will_paginate %> のように、引数を省略した場合、viewに紐付いているコントローラー名をインスタンス変数として自動的に渡す(usersコントローラーなら @users を渡す)事が出来る。
- render にレコードオブジェクトを渡してeach文のような挙動を実現
以下のようなeach文がview内で書かれている場合、
<% @レコードオブジェクト名.each do |イテレーター| %> レコード一つに対して表示したい内容 <% end %>
これを render を使って以下のように書き換える事が出来る。
<%= render @レコードオブジェクト名 %>
こうすることにより、Railsでは、渡したレコードオブジェクトのモデルと紐付けて app/views/コントローラ名/_モデル名(頭文字は小文字).html.erb に @レコードオブジェクト名 を分割して渡すので app/views/コントローラ名/_モデル名(頭文字は小文字).html.erb に レコード一つに対して表示したい内容 を記述。この時のイテレーターは モデル名(頭文字は小文字) になる。
- レコードオブジェクト.toggle(:booleanカラム) : boolean値のカラムを反転(trueならfalse、falseならtrueへ変更)させるメソッド
- % heroku pg:reset DATABASE : heroku(本番環境)上のデータベースのレコードを全削除するコマンド
第11章 アカウントの有効化
- before_create :メソッド名 : レコードが作成される直前のみ動かすメソッドを指定できる。 app/models/モデル名.rb に記述。
- メイラー(メールを自動生成する機能)の作成
-
% rails generate mailer メイラー名(キャメルケース) メソッド名(スネークケース) ...: メイラーを作成するコマンド。メソッド名は送るメールの内容ごとに名付けるべし。 - 送るメールの内容は
app/views/メイラー名/メソッド名.text.erbにテキスト表示の内容、app/views/メイラー名/メソッド名.html.erbにhtml表示の内容をそれぞれ記載する。また、それぞれのレイアウトはapp/views/layouts/mailer*で変更可能。 -
app/mailers/application_mailer.rb: メーラーの設定が書かれている。二行目のdefault from: “メールアドレス”でメールの送り主を設定できる。 - 実際にメールを作成するメソッドは
app/mailers/user_mailer.rbに以下のように書かれておりメイラー名.メソッド名.deliver_nowを呼び出す事により、メールを送信する。
class メイラー名 < ApplicationMail def メソッド名 mail to: 送り先メールアドレス, subject: “メールの題名” end ︙ end
- メイラーが送るテストメールを見る方法
1. cofig/enviroments/development.rb に以下の内容を書き込む。
Rails.application.configure do ︙ config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :test host = ‘Railsアプリのホスト名(ローカル環境なら ‘localhost:3000’)’ config.action_mailer.default_url_options = { host: host, protocol: ‘Railsアプリのプロトコルに合わせる(’https’ or ‘http’)’ } ︙ end
2. test/mailers/previews/メイラー名(スネークケース)_preview.rb にテストメールを書くためのメソッド呼び出しを記述する。
3. Railsアプリを起動して protocol://Railsアプリのホスト名/rails/mailers/メイラー名/メソッド名 をブラウザで開く3。
- CGI.escape(文字列) : URLで扱えない文字列を特殊な文字コードに変換するメソッド
- メイラーのテストは test/mailers/メイラー名(スネークケース)_test.rb に自動生成されており、これを使うために config/enviroments/test.rb に以下の内容を書き加えて、テスト内のドメイン名をメイラーの設定 app/mailers/application_mailer.rb に合わせなければならない
Rails.application.configure do config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = { host: ‘デフォルトのままなら’example.com’’ } end
- メタプログラミング : プログラムを作成するプログラム。黒魔術とも言われる。Railsではモデル内で send(“カラム名”) により、カラムを呼び出せる事を利用したりする
- メイラーに用意されているメソッド
-
ActionMailer::Base.deliveries.size: メイラーによって送信されたメールの数を返す。 -
ActionMailer::Base.deliveries.clear: メイラーによって送信されたメールの数をリセットする。
- レコードオブジェクト.update_columns(カラム名: 更新値, カラム2名: 更新値, ... ) : 複数のカラムの値を更新できるメソッド
- 本番環境 heroku 上で実際にメールを送信する手法
- Herokuアカウントにクレジットカードを設定。
-
% heroku addons:create sendgrid:starterコマンドで、herokuにSendGridというherokuアドオンを付与しstarter tierというサービス(1日に最大400通のメールを作成できる無料サービス)を使用可能にする。 -
config/environments/production.rbに以下の内容を書き加える。
Rails.application.configure do ︙ config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp host = '<your heroku app>.herokuapp.com' config.action_mailer.default_url_options = { host: host } ActionMailer::Base.smtp_settings = { :address => 'smtp.sendgrid.net', :port => '587', :authentication => :plain, :user_name => ENV['SENDGRID_USERNAME'], :password => ENV['SENDGRID_PASSWORD'], :domain => 'heroku.com', :enable_starttls_auto => true } ︙ end
上記の内容は SendGrid アドオンを使う為に、本番環境にSMTPを設定している。user_nameとpasswordは、アドオンが自動生成した環境変数 ENV['SENDGRID_USERNAME'] と ENV['SENDGRID_PASSWORD'] をそれぞれ使用している。