記事一覧表示

Rails チュートリアル読んでみた(その3)

概要

前回の続きで、Rails チュートリアル(第9~11章)を読んだ時に取ったメモです。

第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 に記述。




- メイラー(メールを自動生成する機能)の作成
  1. % rails generate mailer メイラー名(キャメルケース) メソッド名(スネークケース) ... : メイラーを作成するコマンド。メソッド名は送るメールの内容ごとに名付けるべし。
  2. 送るメールの内容は app/views/メイラー名/メソッド名.text.erb にテキスト表示の内容、 app/views/メイラー名/メソッド名.html.erb にhtml表示の内容をそれぞれ記載する。また、それぞれのレイアウトは app/views/layouts/mailer* で変更可能。
  3. app/mailers/application_mailer.rb : メーラーの設定が書かれている。二行目の default from: “メールアドレス” でメールの送り主を設定できる。
  4. 実際にメールを作成するメソッドは 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 上で実際にメールを送信する手法
  1. Herokuアカウントにクレジットカードを設定。
  2. % heroku addons:create sendgrid:starter コマンドで、herokuに SendGrid というherokuアドオンを付与し starter tier というサービス(1日に最大400通のメールを作成できる無料サービス)を使用可能にする。
  3. 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'] をそれぞれ使用している。


- heroku config:get 環境変数名 : heroku上の環境変数の値を確認するコマンド

  1. 参考ページ

  2. 色々な種類のサンプルデータを作る事が出来るので、公式ドキュメントで調べてみよう。

  3. Missing host to link to! ... と言うエラーが出た場合、このページを参考にすると良い。