記事一覧表示

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

概要

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

第6章  ユーザーのモデルを作成する


- rails generate model モデル名(単数形) カラム名:オブジェクトの型 ... : 新しいモデルを作成




- rails db:rollback : データベースに加えた変更を一つ戻す。また、データベースを任意のバージョンに戻したいときは rails db:migrate VERSION=任意のバージョン




- rails console --sandbox : console中で行った変更を全て取り消しにするモード。起動中はデータベースをロックする為、テーブルへの変更 rails db:migrate が弾かれる。よって rails db:migrate を行う時は、consoleは切るべし。




- レコードの更新方法は レコードオブジェクト.update_attributes(カラム名: “変更後のデータ”, カラム名: “変更後のデータ”, ... )




- modelのテストは test/models/モデル名_test.rb




- レコードオブジェクト.errors.full_messages : modelのバリデーションエラーを表示するコード。また、errorsは、ハッシュとして保存されているので レコードオブジェクト.errors.add(:カラム名, “エラーメッセージ”) とすることで独自のエラーメッセージを追加できる




- 新しいレコードオブジェクト = 複製するレコードオブジェクト.dup : レコードオブジェクトの複製




- before_save { レコードを追加する前に行う処理 } : テーブルにレコードを追加する前に動くコールバックメソッド。 app/models/モデル名.rb に記述




- app/models/モデル名.rbhas_secure_password を記述すると、以下の機能を取得
  • password_digest と言うカラムに、ハッシュ化した(不可逆の)パスワードを保存出来る( has_secure_password を使用するにはテーブルに password_digest と言うカラムを事前に作る必要がある)。
  • passwordpassword_confirmation と言う、仮想的な(テーブルには存在しない)カラムが作られる。このカラムには一意性と存在性(nilやnullの禁止)のバリデーションが設定されているので、テーブルにレコードを追加する時には、必ずこれらのカラムにはパスワードを入れないといけない(逆にレコードの追加以外、例えばpasswordの更新には適用されないので app/models/モデル名.rbpassword のバリデーションを記述した方が良い)。
  • authenticate という、引数の文字列がパスワードと一致するとモデル内のレコードを、間違っているとfalseを返すメソッドが使えるようになる。


- bcrypt : has_secure_password がパスワードをハッシュ化する時に用いるハッシュ関数。Gemfileに追加してインストール




- heroku run heroku環境で実行したいコマンド : heroku環境下で実行したコマンドの結果が返ってくる。例えば、heroku run rails db:migrateheroku run rails console --sandbox などで、開発環境で加えたデータベースの変更の更新やheroku環境下でのデバックなどが可能になる




- rails generate migration 操作名_to_テーブル名_カラム名 : テーブルカラムに特定の操作を行う為のファイル(マイグレーション)を作成。操作名の書き方には慣習がある?




- rails generate migration add_追加するカラム名_to_テーブル名 追加するカラム名:オブジェクトの型 : テーブルに新しいカラムを追加する時のマイグレーションを作成。




- 便利なマイグレーションメソッド : db/migrate/[timestamp]_操作名_to_テーブル名_カラム名.rb に記述する内容
  • add_index :テーブル名, :カラム名, unique: true : テーブルカラムに対して、索引機能(index)を追加し、オプション unique: true でカラムに同じ文字列の重複を禁止(一意性を確立)している。因みにカラム名を指定する所を [:カラム名, :カラム2名] のように複数のカラムを一つのリストにして指定すると、複合キーインデックス(互いのカラムのインデックスを組み合わせた複合インデックス)を作成できる。これは2つのカラムで一つのレコードを検索する速度を上げる。


- 便利なバリデーション
  • presence: true : カラムにnilやnullの禁止(存在性を確立)を設定。
  • length: { maximum: 最大文字数 } : カラムに含む最大文字数を設定。
  • format: { with: 正規表現 } : カラムに含む文字列を正規表現にマッチした文字列のみに設定。
  • uniqueness: true : カラムに一意性を設定。 true の代わりにオプション { case_sensitive: false } を記述すると、大文字・小文字の区別を無くす( user@example.comUSER@EXAMPLE.COM を同じ物として扱う)。
  • allow_nil: true : 値にnilを含む事を承諾。


- マイグレーションメソッドとバリデーションは Active Record と言うRailsライブラリに入っている




- 便利な正規表現
  • / : 正規表現の開始と終わりを示す。
  • [クラスと文字列の複合文] : クラスと文字列の複合文が表す文字列の内のどれか一文字を示す。
  • (クラスと文字列の複合文) : クラスと文字列の複合文が表す文字列を示す。
  • パターン+ : 直前のパターンを一回以上繰り返す。
  • パターン* : 直前のパターンを0回以上繰り返す。
  • \ : エスケープ。これ以降の文字に有効(複数指定可)。
  • \A : 文字列の先頭を示す。
  • \z : 文字列の終わりを示す。
  • a-z : 英字の小文字を示す。
  • \w : 英字の小文字と大文字、数字、アンダースコア _ を示すクラス。
  • \d : 数字を示すクラス。
  • . : 改行( \n\r )以外の全ての文字を示す。
  • i : 大文字・小文字の区別を無視するオプション。正規表現の終わり / の後ろに記述。





第7章  ユーザー登録


- Railsには、デフォルトでテスト環境 test 、開発環境 development 、本番環境 production の3つの環境が用意されており、アプリの起動中に使用している環境名は Rails.env に格納されている。また、コマンドを実行する時に、どの環境に適用させるかを以下のように指定出来る(指定がなかった場合は自動的に development が使用される)
  • rails console 環境名 : 特定環境下でのconsole実行。
  • rails server --environment 環境名 : 特定環境でのアプリを起動。
  • rails db:migrate RAILS_ENV=環境名 : 特定環境下のデータベースを変更。


- params : ページに設定されているコントローラとアクションをYAML形式で保存している変数。




- <%= debug(params) if Rails.env.development? %> : アプリ実行中にデバック情報(params)をページ内に表示させるためのコード。if文で開発環境以外には表示させないようにしている。ビューファイル内に記述




- SCSS(Sass)のミックスイン : 何度も使うスタイルをパッケージ化し、必要な所で呼び出し可能
@mixin シート名 {
  スタイルを記述
}

~~ {
  /* 必要な所で呼び出し */
  @include シート名;
}




- resources :コントローラ名 : コントローラにRESTful(リレーショナルデータベースの作成/取得/更新/削除 (Create/Read/Update/Delete: CRUD) 操作)を割り当てられたリソースを実装。取り扱うリソースを指定する時は、後ろに , only: [:リソース(アクション)名] を続ける。 config/routes.rb に記述




- debugger : app/controllers/コントローラー名_controller.rb のアクションメソッド内に書くと、そのメソッド内の debugger 行がアプリ内で呼び出された時に rails server のログにconsoleが出現し、デバックを行う事が出来る byebug gemに入っているメソッド。




- Gravatar : プロフィール写真をメールアドレスと紐付けて管理してくれる無料サービス
  • 登録 : gravatar_id = Digest::MD5::hexdigest(登録するメールアドレス.downcase) で登録可能。メールアドレスはMD5と言う仕組みでハッシュ化され登録される。Rubyでは、その仕組みをDigestライブラリのhexdigestで実現している。登録が成功するとidが返ってくる。
  • 画像の挿入 : メールアドレスを登録すると https://secure.gravatar.com/avatar/gravatar_id と言うURLにプロフィール写真が作成されるので、挿入したい所にimage_tagを使う。例えば image_tag(URL, alt: ユーザ名, class: “gravatar”) みたいな感じ。


- form_forヘルパー : ページ上にformを作成するのに便利なヘルパー

 モデルオブジェクトをレコード毎に分割してイテレータに渡し、レコード内のカラム毎にフォーム作成できる。

<%= form_for(モデルオブジェクト) do |f| %>
  #カラム名(formの題目)を表示
  <%= f.label :カラム名, “カラム名の代わりに置きたい題目(任意)” %>
  #フォームを作成
  <%= f.inputタイプ_field :カラム名, オプション(class: や id: 指定とか) %>

  <%= f.label :カラム2名, “カラム2名の代わりに置きたい題目(任意)” %>
  <%= f.inputタイプ_field :カラム2名, オプション %>
     ︙
  <%= f.submit “ボタンに載せたいメッセージ”, class: "btn btn-primary" %>
<% end %>

 inputタイプには text, email, password などがあり、それぞれのタイプで作られたformには、タイプ毎に必要な機能(passwordには入力データの隠遁機能、emailにはモバイル端末で動作した時のキーボード機能など)が付いている。また、Railsはformに渡されたモデルオブジェクトがモデルである事を認識しており、モデル(テーブル)内にモデルオブジェクトが無い( モデルオブジェクト = モデル名.new で作成していた)場合、このフォームがPOSTリクエスト( /モデルコントローラ名 へのPOST)である事を推定してくれる。もし、POST先を変更したい場合は モデルオブジェクト の所を モデルオブジェクト, url: POST先 に変更する。また、モデルオブジェクトが無い場合は、モデルオブジェクトの代わりに :paramsに渡す属性名 を渡す。


- class: ‘form-control’ : htmlタグのクラスを form-control と指定すると、ページ内のフォームの位置が変化した時(エラー文の表示など)にBootdtrapがフォームの位置を上手く取り扱ってくれる




- params.require(:属性名).permit(:属性内の属性, :属性内の属性2, ...) : URLに渡されたparamsハッシュの内、特定の属性しか認めないようにするコード。外部で作られたparamsハッシュの特定外の属性を弾く機能を持つ(第三者によるモデル内の更新されて欲しくないカラムの更新を防ぐ)




- pluralize(数字, “英単語”) : 返り値として 数字 英単語の複数形or単数形 を表示するメソッド




- flash[:処理結果] = “メッセージ” : railsにはflashという変数が用意されており、ここに処理結果を示す際のメッセージを入れてページに渡し、ページ上で出力する。また、Bootstrap CSSには、flash用に4つのスタイル(success、info、warning、danger)を持って居るので、処理結果はこの4つのどれかを使うのが好ましい




- SSLの導入 : config/environments/production.rbconfig.force_ssl = true 行をコメントアウト。これにより、アプリ越しのデータを暗号化し、外部からの読み取りを防ぐ




- HerokuのデフォルトのサーバーはRubyだけで実装されたWEBrickを使用しているが、このサーバはスレッドとプロセスを一つずつしか持っていないので、同時に複数のリクエストが来た時に、一つずつしか処理を行えない。よって、Webサービスのサーバーとしては不適切である




- Puma(本番環境用)サーバーをHerokuに設定
  1. Gemfileで puma gem をインストール(Railsではデフォルトで入っているのでこの操作は無視)。
  2. config/puma.rb と言う設定ファイル(汎用例)を作成。
  3. Heroku上でPumaのプロセスを走らせる ./Profile と言う設定ファイルを作成。ファイルの中身は web: bundle exec puma -C config/puma.rb
  4. 変更をherokuにpushし、アプリを起動。





第8章  基本的なログイン機構


- flash.nowとflash
  • flash.now[:処理結果] = ‘メッセージ’ : 現行リクエストのみに有効なメッセージを保持。 render は現行リクエスト内で使うviewを指定する(新しいリクエストを作らない)ので、この場合にページ内で使いたいメッセージを保持。
  • flash[:処理結果] = ‘メッセージ’ : 次(一つ先)のリクエストまで有効なメッセージを保持。 redirect_to は現行リクエスト内から別のアクションを利用する(新しいリクエストを作成する)ので、この場合に移り先で使いたいメッセージを保持。


- SessionsHelper : Railsのセッション(コンピュータ間で設定する半永続的な接続。Cookiesなど)用ヘルパーが格納されているモジュール。 app/controllers/application_controller.rb にincludeして、全コントローラ内で使用




- BootstrapのJavaScriptライブラリとjQueryを読み込む(dropdownクラスやdropdown-menuなどを使えるようにする)為に app/assets/javascripts/application.js に以下を記入
//= require jquery
//= require bootstrap




- BCrypt::Password.create(‘パスワード’, cost: cost) : has_secure_password でパスワードを暗号化しているメソッド。costは、暗号化を解く際に使う計算コストで、高くすると暗号からパスワードに戻すのが困難になっていく。また、実際はテスト環境では低く見積もり、本番環境では高く見積もるようにするので、以下のように求める。
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                              BCrypt::Engine.cost




- test用テーブルのレコード(fixtures)を作成する時は test/fixtures/テーブル名.yml に以下のように記述
シンボル名:
  カラム名:カラム2名: 値
     ︙

 呼び出す時は 変数 = テーブル名(:シンボル名) をtest内で記述。


- セッション用ヘルパー : SessionsHelper に格納されているヘルパー
  • session[:シンボル名] = 保存する値 : 一時cookiesをブラウザ内に保存。保存される時、データは暗号化される。
  • session.delete(:シンボル名) : シンボル名に該当するブラウザ内のcookiesを削除。


- 便利なアサーション
  • assert_not 判定文 : 判定文がfalseの時、テスト成功。
  • assert 判定文 “エラーメッセージ” : 判定文がtrueの時、テスト成功。falseの時は、エラーメッセージを出力。
  • assert_no_difference ‘検査する変数’ do 検査処理を記述 end : 検査処理(例えば、POSTリクエスト)の前後で検査する変数の中身が変化しなかったらテスト成功。
  • assert_difference ‘検査する変数’, 検査処理の前後の変数数値の差 do 検査処理を記述 end : 検査処理の前後で検査する変数の中身が変数数値の差だけ変わったらテスト成功。
  • assert_redirected_to リダイレクト先 : リダイレクト先が正しかったらテスト成功。
  • follow_redirect! : redirect先のページに移動。リクエスト後の遷移先のflashテストとかに使う。
  • assert_template ‘コントローラ名/ページ名’ : renderされているページに正しいテンプレートが使われていたら、テスト成功。
  • HTTPリクエスト リクエスト先 : リクエストが通ったらテスト成功。postやdeleteなどのリクエストにparamsが必要な場合、直後に , params: { シンボル名: { 属性名: 値, 属性名2: 値, ... } } のように書く。
  • assert_match 正規表現or文字列, 検査する文字列 : 検査する文字列の中に正規表現or文字列に一致した文字列がある時、テスト成功。