Railsチュートリアルで躓くところまとめ(4章~6章)

titleタグの設定

チュートリアルの4章で出てくる

<% provide(:title, "Home") %>

provideをビューに記述することによってそれぞれのページのタイトルを設定できる。

<title><%= full_title(yield(:title)) %></title>

fulltitleメソッドはapp/helpers/application.helper.rbで定義する

module ApplicationHelper
  # ページごとの完全なタイトルを返します。
def full_title(page_title = '')
  base_title = "Ruby on Rails Tutorial Sample App"
  if page_title.empty?
    base_title
  else
    page_title + " | " + base_title
  end
end
end

以上の作業を完了させると、ページごとにタイトルを設定することが可能になる

BootStrapの導入

5章ででてくる
gemファイルにbootstrapを導入するための文記述。→その後bundle install。指定の構文をscssにimportする。すると自動的に一部のスタイルがととのえられている。(bootstrap導入による効果らしい)

Gemfileに追加する構文
gem ‘bootstrap-sass’, ‘3.3.7’

importの構文

@import "bootstrap-sprockets";
@import "bootstrap";

パーシャル

パーシャルは共通部品を扱う仕組みのことで、共通部品として扱いたいhtml.erbのファイル名の先頭に _ アンダーバーをつける。アンダーバーのつけ忘れに注意。

  1. アンダーバーをつけわすれたままテキストエディタを開く
  2. そのあとにファイル名を修正する。
  3. ファイル名を編集しても、開いているのはアンダーバーをつけわすれたままのファイル

このようによくわからないことになってしまうので、もしパーシャルにアンダーバーをつけ忘れたら、一旦ファイルを閉じてから、ファイル名を修正→その後またテキストエディタで開く。パーシャルを表示するには<%= render()%>を使用する。

<!--[if lt IE 9]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
  </script>
<![endif]-->
<%= render("layouts/shim")%>

拡張子をつけずに「フォルダ名/ファイル名」のような形式で記述しているのにも注目。

どういうときにパス指定できる?

link_to()ヘルパーにpathキーワードをつかってurlを指定することがあるが、ルーティンでrootを示す記号 / を使うとpathキーワードを使用できる。

rails routesコマンドでルーティングを確認すると、Prefixが指定されているのがわかる

Rails.application.routes.draw do
  root("static_pages#home")
  get '/help' => "static_pages#help" #<%= link_to("help", help_path)%>
  get '/about'=> "static_pages#about"
  get "/contact" => "static_pages#contact"
end

validates

validatesはテーブルへの不正な投稿を防ぐしくみ。railsチュートリアルでは6章ででてくる。

validatesが反映されない
rails consoleでvalidatesを検証しようとするとvalidatesを設定したのに反映されないということがおこる。そういうときは一旦rails consoleを終了して再度立ち上げる。環境によってはおこらないトラブルかもしれない。

emailの検証
emailの検証もvalidatesで設定することができる。VALID_EMAIL_REGEXという正規表現で検証している

class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :name, {presence: true, length: {maximum: 50}}
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
 #2つの連続したドットはマッチさせない
 #VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates :email, {
    presence: true,#空文字を許さない
    length: {maximum: 265},#265文字以上を許さない
    format: { with: VALID_EMAIL_REGEX },#マッチしないメルアドは許さない
    uniqueness: true#重複したメールアドレスの登録を制限
    }
end

before_save
before_saveはActiveRecordのコールバックメソッドで(意味不明)。データベースにオブジェクトが保存される前に実行されるらしい。上記コードの例では、大文字でメールがわたってきても小文字に変換するようにしている。self.email = email.downcaseはの部分はemail.downcase!のみとすることも可能。

class User < ApplicationRecord
  before_save { email.downcase! }
end

  • 大文字小文字を無視する → uniqueness: { case_sensitive: false }
  • 最小文字数を設定する → length: {minimum: 6}

has_secure_password

has_secure_passwordはパスワードを暗号化させるために使う。has_secure_passwordを使うためには必ずテーブルにpassword_digestというカラムを持たせる必要がある。またhas_secure_passwordを使うためのgemをインストールする必要がある。そのためまずはrailsコマンドでマイグレーションファイルを作成する。

1.has_secure_passwordを使うためpassword_digestカラムを追加する作業

$ rails generate migration add_password_digest_to_users password_digest:string

マイグレーションファイルが適切かどうか確認する

class AddPasswordDigestToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :password_digest, :string
  end
end

適切だったらrails db:migrate でテーブルに反映させる

2.gemをインストール
Gemfileに gem ‘bcrypt’, ‘3.1.12’ を記述したあと bundle installを実行してgemを更新する

3.モデルファイルにhas_secure_passwordを記述

class User < ApplicationRecord
    has_secure_password
end

いろいろごちゃごちゃしているがパスワード暗号化の要点は

  • password_digestカラムを追加する必要がある
  • bcryptというgemを追加する必要がある
  • モデルファイルにhas_secure_passwordを追加する
  • モデルオブジェクトの生成時にpassword_digestではなくpasswordを指定する

最後の4点目は重要でインスタンス生成時にpasswordを指定しないと暗号化されない。なんでこんなややこしいのだろうか。password_digestとした場合はエラーにはならず。きちんとテーブルに追加される。しかし暗号化はされない。

暗号化されたパスワードに簡易的にログイン
rails consoleでuserのインスタンスを生成し、!!user.authenticate(“password”)の引数にパスワードを渡す。引数のパスワードが正しければtrueが返ってくる。