Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

【Ruby on Railsチュートリアル(第4版)】第2章 Toyアプリケーション(演習と解答)

はじめに

このブログ記事は、私(Kodak)自身のRailsの勉強記録として書いています。
Ruby on Railsチュートリアル』の演習と解答をもくもくと書いているだけの記事なので、興味の無い方は軽くスルーしてあげてください。他にも、まだ『Railsチュートリアル』の演習に挑戦していない方、これから『Railsチュートリアル』をやるぞ!という方は(演習の解答の)ネタバレになりますので、スルーしてください。

Ruby on Rails チュートリアルとは?

Ruby業界でRailsを使い始めるなら、まず最初に初めるRails入門サイトです。
電子書籍版は有料ですが、Webサイトにあるオンライン版は無料なので、誰でも読む(Railsにチャレンジする)事ができます。
railstutorial.jp
全部で14章あり、かなりのボリュームですが、これを読む事でRailsの基礎を学ぶ事ができ、ちょっとしたWebアプリケーションを作れるレベルにはなれる?とのこと。
各章毎に演習問題が複数あり、これを解いていく事でRailsへの理解を深めていく事ができる様になっています。

環境について

Ruby 2.5.0-dev
Rails 5.1.4
・バージョン管理ツール:GitHub(https://github.com/Kodak4400)

演習と解答

2.2.1 ユーザーページを探索する<演習>
1. CSSを知っている読者へ: 新しいユーザーを作成し、ブラウザのHTMLインスペクター機能を使って「User was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?
【解答】消える。

2. emailを入力せず、名前だけを入力しようとした場合、どうなるでしょうか?
【解答】正常終了して、emailなしのユーザーが作成される。

3. 「@example.com」のような間違ったメールアドレスを入力して更新しようとした場合、どうなるでしょうか?
【解答】正常終了して、間違ったメールアドレスでユーザーが作成される。

4. 上記の演習で作成したユーザーを削除してみてください。ユーザーを削除したとき、Railsはどんなメッセージを表示するでしょうか?
【解答】「User was successfully destroyed.」と表示される。


2.2.2 MVCの挙動<演習>
1. 図 2.11を参考にしながら、/users/1/edit というURLにアクセスしたときの振る舞いについて図を書いてみてください。
【解答】以下の通り。
f:id:special-moucom:20180625014113p:plain

2. 図示した振る舞いを見ながら、Scaffoldで生成されたコードの中でデータベースからユーザー情報を取得しているコードを探してみてください。
【解答】以下の通り。
■users_controller.rb

    def set_user
      @user = User.find(params[:id])
    end

3. ユーザーの情報を編集するページのファイル名は何でしょうか?
【解答】users/edit.html.erb


2.3.1 マイクロポストを探検する<演習>
1. CSSを知っている読者へ: 新しいマイクロポストを作成し、ブラウザのHTMLインスペクター機能を使って「Micropost was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?
【解答】消える。

2. マイクロポストの作成画面で、ContentもUserも空にして作成しようとするどうなるでしょうか?
【解答】作成される。

3. 141文字以上の文字列をContentに入力した状態で、マイクロポストを作成しようとするとどうなるでしょうか? (ヒント: WikipediaRubyの記事にある1段落目がちょうど150文字程度ですが、どうなりますか?)
【解答】作成される。

4. 上記の演習で作成したマイクロポストを削除してみましょう。
実機操作のため割愛。


2.3.2 マイクロポストをマイクロにする<演習>
1. ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示してみましょう。同ファイル内の他のコードから文法を推測してみてください (コラム 1.1で紹介した技術の出番です)。うまく表示できたかどうか、/users/1 にアクセスして確認してみましょう。
実機操作のため割愛。

2. リスト 2.16は、マイクロポストのContentが存在しているかどうかを検証するバリデーションです。マイクロポストが空でないことを検証できているかどうか、実際に試してみましょう (図 2.16のようになっていると成功です)。
実機操作のため割愛。

3. リスト 2.17のFILL_INとなっている箇所を書き換えて、Userモデルのnameとemailが存在していることを検証してみてください (図 2.17)。
実機操作のため割愛。

【箱根湯本】月の宿 紗らでマタニティプランを満喫しました

今回は、久しぶりにブログらしいブログです。

はじめに

うちの嫁さんが子供を授かって約6ヵ月が過ぎようとした時に「最後の2人の旅行がしたい。」と言っていたので、旅行に行ってきました。妻のお腹の子も大きくなり、遠出は難しいと判断して、行き先は電車で片道1時間半圏内の「箱根湯本」にしました。

12:00頃 箱根湯本駅到着

f:id:special-moucom:20180610220439j:plain

ちょっと遅めに箱根湯本駅に到着です。
今回の旅は、妻の体に無理をさせない様、歩き回る観光ではなく、温泉に『しっぽり』と浸かって、日々の疲れを癒やそう。という事を目的としていました。
なので、朝も慌てる事無く、ゆっくりとロマンスカーに乗って箱根湯本駅に向かっていました。

12:30頃 昼食前

f:id:special-moucom:20180610220711j:plain

昼食を食べに『はつ花 そば』に向かう途中『焼きモンブラン』という看板が目に入りました。思わず寄り道して『焼きモンブラン』と『九頭竜餅』を購入。
昼食前ですが、美味しくいただきました。
『焼きモンブラン』は、モンブランが焼かれているのは勿論、中に栗が丸々1つ入っていて驚きました。『九頭竜餅』は、見た目は饅頭なのに、お餅のように生地が柔らかく、とても不思議な感じでした。もちろん両方ともとても美味しかったです。

13:00頃 昼食

f:id:special-moucom:20180610220731j:plain

以前から、箱根湯本に来たら1度は食べて見たかった『はつ花 そば』
というのも、私は「とろろ」が大好きで、その道の名店ともなれば是非とも行ってみたかったですよね。

あと、この時、初めて知ったのですが、私はずっと山芋という種類の芋があり、それを剃ったものが「とろろ」だと思っていたのですが、実は山芋とよばれる種類の芋は存在せず、自然薯、大和芋、長芋をまとめて山芋って呼とび、それらを剃ったものを纏めて「とろろ」と呼ぶらしいです。お恥ずかしながら1つ勉強になりました。

山芋・長芋・大和芋・自然薯の違いって?とろろ芋とはどれのこと? | 彩とりどりの世界

『はつ花 そば』のそば(貞女そば)は「とろろ」好きの人にはたまらない1品でした。 そばが「とろろ」に絡んでいるせいか、1口で食べるそばの量が多く、直ぐに食べ終えてしまったので、1品だけだとちょっと物足りない感じもしました。
しかし、まぁ腹八分目で考えるなら量は丁度良く、とても美味しく頂けました。

箱根湯本のお食事(昼食・ランチ・夕食・お土産)なら 自然薯蕎麦の、はつ花そば

14:00頃 ホテル 月の宿 紗らに到着

f:id:special-moucom:20180610220751j:plain

ホテルは、月の宿 紗らです。館内、部屋はとても綺麗で凄くお洒落でした。
(注:写真のベットがくしゃくしゃなのは、私が部屋に入って直ぐにベットにダイブしたからです。決して最初からくしゃくしゃだったワケではございません。)
今回はマタニティプランでの宿泊という事で、特に食事に対しては大変気を配って頂けました。
具体的には「食前酒」→「ジュース」、「生魚」→「湯葉」への変更やノンアルコールの飲み放題(もちろん旦那はアルコール飲み放題)等です。
また、これら料理についても従業員の方から丁寧に説明があり、大変満足しました。

最後に温泉ですが、大浴場と貸切風呂と2種類があり、貸切風呂については空いてさえすれば何時でも、何回でも入浴OKとの事でした。

いやぁ本当に幸せでした。豪華な食事に温泉。しかも綺麗な部屋で心も体も大満足でした。

www.hotespa.net

最後に

これにて「最後の2人の旅行」終了です。
次の旅行は何時になるやら・・・
そして、次の旅行の時には自分達の子供が居て、きっと大変なんだろうなぁ・・・と色々と考えさせられる旅行でもありました。

【Ruby on Railsチュートリアル(第4版)】第1章 ゼロからデプロイまで(演習と解答)

Ruby on Rails チュートリアルとは?

Ruby on Railsチュートリアル: RailsでWeb開発を学ぶ』私もこの様なWebサイトがある事を知らなかったのですが、Ruby業界でRailsを使い始めるなら、まず最初に初める入門サイトだそうです。電子書籍版は有料ですが、Webサイトにあるオンライン版は無料なので、誰でも読む事ができます。
railstutorial.jp

全部で14章あり、かなりのボリュームですが、これを読む事でRailsの基礎を学ぶ事ができ、ちょっとしたWebアプリケーションを作れるレベルにはなれる?とのこと。
各章毎に演習問題が複数あり、これを解いていく事でRailsへの理解を深めていく事ができるそうです。

さて・・・?

これからですが、私も少しずつですが、このRuby on Railsチュートリアルに挑戦したいと思います。
進捗記録用に演習問題の解答をブログに書きつつ理解を深めていこうと思います。
演習の解答はネタバレを含みますので、まだ演習に挑戦していない方のために、チュートリアルのブログはひっそりとアップロードする方針で行こうかと思います。

演習と解答

<演習>
1. デフォルトのRailsページに表示されているものと比べて、今の自分のコンピュータにあるRubyのバージョンはいくつになっていますか? コマンドラインruby -vを実行することで簡単に確認できます。
【解答】以下の通り。

$ ruby -v
ruby 2.6.0dev (2018-03-11 trunk 62724) [x86_64-darwin16]

2. 同様にして、Railsのバージョンも調べてみましょう。調べたバージョンはリスト 1.1でインストールしたバージョンと一致しているでしょうか?
【解答】以下の通り。

$ rails -v
Rails 5.1.4

<演習>
1. リスト 1.7のhelloアクションを書き換え、「hello, world!」の代わりに「hola, mundo!」と表示されるようにしてみましょう。
【解答】以下の通り。
■app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html: "hello, mundo!"
  end
end

2. Railsでは「非ASCII文字」もサポートされています。「¡Hola, mundo!」にはスペイン語特有の逆さ感嘆符「¡」が含まれています (図 1.16)。「¡」文字をMacで表示するには、Optionキーを押しながら1キーを押します。この文字をコピーして自分のエディタに貼り付ける方が早いかもしれません。
【解答】以下の通り。
■app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html: "¡hello, mundo!"
  end
end

3. リスト 1.7のhelloアクションを参考にして、2つ目のアクションgoodbyeを追加しましょう。このアクションは、「goodbye, world!」というテキストを表示します。リスト 1.9のルーティングを編集して、ルートルーティングの割り当て先をhelloアクションからgoodbyeアクションに変更します (図 1.17)。
【解答】以下の通り。
■app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html: "¡hello, mundo!"
  end

  def goodbye
    render html: "goodbye, world!"
  end
end

■config/routes.rb

Rails.application.routes.draw do
  # root 'application#hello'
  root 'application#goodbye'
end

Railsの国際化機能を使って日本語/英語を切り替える機能を実装

学びシリーズ第4弾です。

作ってみた機能

Railsの国際化機能を使って日本語/英語を切り替える機能を実装

環境構成

全体構成・完成イメージ

f:id:special-moucom:20180522013228p:plain

DB(Table)

なし

プログラムコード等

Config


今回は、多くのConfig設定を行います。

■ config/application.rb

config.i18n.default_locale = :ja

デフォルトのロケールを日本語表記に設定します。

  • ロケールとは?
    ソフトウェアに内蔵される、言語や国・地域ごとに異なる単位、記号、日付、通貨などの表記規則の集合。または単に、利用する言語や国・地域の指定のこと。(IT用語辞典より)

■ config/routes.rb

get "locale" => "managers#locale", as: "locale"

日本語表記/英語表記を切り替えるroutesを設定します。

■ config/locales/en.yml config/locales/ja.yml

ja:
  activerecord:
    models:
  attributes:
    manager:
      manager_name: ユーザー名
      password: パスワード

en:
  activerecord:
    models:
  attributes:
    manager:
      manager_name: UserName
      password: Password
  

日本語表記と英語表記のロケール用のテキストをYAML形式で作成します。

Controller


■ managers_controller.rb

class ManagersController < ApplicationController

  def locale
    if ["ja", "en"].include?(params[:locale])
      cookies[:locale] = params[:locale]
      redirect_to :root
    end
  end
  
end

ここでcookieにViewから受け取った日本語表記("ja")/英語表記("en")の値をセットする。

■ application_controller.rb

  before_action :set_locale

  def set_locale
    if ["ja", "en"].include?(cookies[:locale])
      I18n.locale = cookies[:locale]
    end
  end

cookieに保存された日本語表記("ja")/英語表記("en")をGemパッケージのrails-i18nに読み込ませて、表記を変更します。

以下は、ご参考です。

View


■ members/index.html.erb

<%= form_tag :session do %>
  <table id="login_form">
    <tr>
      <td style="text-align: right"><%= t('attributes.manager.manager_name') %></td>
      <td><%= text_field_tag "manager_name", "", style: "width: 120px" %></td>
    </tr>
    <tr>
      <td style="text-align: right"><%= t('attributes.manager.password') %></td>
      <td><%= password_field_tag "password", "", style: "width: 120px" %></td>
    </tr>
    <tr>
      <td colspan="2" style="text-align: center">
        <%= submit_tag "ログイン" %></td>
    </tr>
  </table>
<% end %>

<%= link_to "日本語", locale_path(locale: "ja") %>
<%= link_to "英語", locale_path(locale: "en") %>

学んだ事

よくサイト等で見る日本語表記/英語表記の切り替え方を学びました。これで、グローバル化にも対応できますね。今はある書籍を使ってRailsの勉強をしていますが、Railsチュートリアルなるものがあるとのことなので、今後はそちらも使って学習していこうと思います。

RailsのSession有無判定による画面制御の実装

学びシリーズ第3弾です。

作ってみた機能

RailsのSession有無判定による画面制御の実装

環境構成

全体構成・完成イメージ

f:id:special-moucom:20180508231202p:plain

[DB]TABLE

なし

プログラムコード等

Controller


■ application_controller.rb

class ApplicationController < ActionController::Base

  class Forbidden < StandardError; end ・・・ 1

  rescue_from Forbidden, with: :rescue_403  ・・・ 2

  private
  def current_manager ・・・4
    # 遅延初期化ロジックに書き換え
    # Manager.find_by(id: session[:manager_id]) if session[:manager_id]
    if session[:manager_id]
      # @current_memberオブジェクトが存在しない場合のみ実行
      @current_manager ||= Manager.find_by(id: session[:manager_id])
    end
  end
  helper_method :current_manager

  def login_required ・・・ 3
    raise Forbidden unless current_manager
  end

  def rescue_403(exception) ・・・ 2
    render "errors/forbidden", status: 403, layout: "error", formats: [:html]
  end
  
end
  1. Forbiddenクラスを作成し、StandardErrorクラスに継承させます。
  2. rescue_fromメソッドを使って、エラーハンドリングできるようにします。上記の場合、Forbiddenエラーが発生した時にrescue_403メソッドを呼ぶようにしています。rescue_403メソッドでは、Forbiddenエラーが起きた時にエラー用のViewを呼び出す様に記載しています。viewsディレクトリ配下にerrorsフォルダを作成し、forbidden.html.erbを作成します。あとはエラーなので、statusに403を設定。error用のlayoutを使用。jpg等の拡張子付きのパスを入力されてもhtmlでエラー画面を表示する様にformatsオプションを設定します。
  3. Sessionを持たない場合に、Forbiddenエラーが発生させるメソッドを作成します。あとは、Controllerに「before_action :login_required」と記載するだけで、このメソッドを呼ぶ事ができます。
  4. 学びシリーズ第二弾で作成したcurrent_managerメソッドも少し改良を加えて、遅延初期化ロジックに書き換えています。遅延初期化とは、事前にオブジェクトや変数に値を設定しておくのではなく、オブジェクトや変数に値が設定されていない(存在しない)時にだけ値を設定することを言います。Rubyプログラマはこういった遅延初期化ロジックを好む人が多いみたいです。でも、たしかに無駄の無いロジックですし右辺の実行回数も減るのでこちらの方がスッキリしますね。

以下、ご参考です。

ERB


■ error.html.erb(layout)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      <%= @page_title %>
    </title>
  </head>
  <body>
    <%= link_to "戻る", :root %>
    <%= yield %>
  </body>
</html>

■ forbidden.html.erb

<% @page_title = "Forbidden" %>
<h1>403 Forbidden</h1>
<p>このページにはアクセスできません。</p>   

学んだ事

Session有無判定によって画面の表示/非表示を切り替える機能は、セキュリティ的に大変重要な機能の1つだと思うのですが、Railsだと以外と簡単に実装できる事に驚きました。Session有無が判定できる事で、ログインしていないと見せられない画面や機能や表示もコントロールできるので、できる事の幅が大きく広がった気がします。また、遅延初期化というのも初めて知りました。こちらも大変勉強になりました。