オレマトペ

Webエンジニアを目指し学習中のデブアラサーによるほぼ擬音ブログ

Ruby on Rails チュートリアル第8章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

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

この章では簡単なログイン・ログアウト機能を実装していきます。

HTTPはステートレス(状態がない)なため、リクエストが終わると前の状態を全て忘れてしまう。
これではログイン状態を次ページでも維持できないため、セッションと呼ばれる半永続的な接続をWebブラウザと、 Rialsサーバー間で確立させ、状態を維持させます。
セッションの確立には、Sessionメソッド・cookiesメソッドと色々あるみたいですが、
まずはSessionメソッドを使用します。

GenerateコマンドでSessionsコントローラを作成し、ルーティングファイルを編集して、 ログインビューを作成していきます。

ログイン画面に入力されたユーザー名、メールアドレスはparamsハッシュから簡単に取り出せる。
具体的にはparamsハッシュの中に、sessionsハッシュが格納されており、
さらにその下にemailとpasswordの入力値が格納されています。

これらの値を元にDBからfind_byでユーザ情報を取り出し、パスワードをauthenticationメソッドを用いて認証します。

また、ログイン失敗時にflashメソッドでエラーメッセージを表示するのですが、
リダイレクトをせずに単純に再レンダリングしているので、
アクション実行後のみならずHome画面にもどってエラーメッセージが表示されてしまいます。
そこで、flash.newメソッドをつかってアクション実行後のみエラーメッセージを表示するように変更します。
リダイレクトをその後に用いるかどうかで、flash or flash.newのどちらを使うか使い分けるらしいです。

Sessionsコントローラを生成して時点で、Sessionsヘルパーモジュールも自動的に作成されているので、
全てのコントローラの親クラスで、Sessionsヘルパーモジュールを読み込みます。
そして、このモジュールにsessionメソッドを使用して、ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDを作成します。

この一時cookiesを攻撃者は盗み出せるみたいですが、それを使って本物のユーザーとしてログインすることはできないみたいです。(言い切ってますね) ただし、この後に出てくるcookiesメソッドで確立される永続的セッションでは、常に盗み取られる可能性がつきまとうそう。

またログイン済みかどうかでヘッダーの表示を切り替えるため、ヘルパーメソッドを作成し、
それを用いてerbファイルに条件分岐でレイアウトを変更するようにしました。
すこしerbファイル自体が複雑になるので、すっきり見やすくする方法があればいいなと思いました。

また統合テストではルーティングやデータベースの更新、レイアウトの変更などが正しく行われるかまで確認しました。

あとがき

ちょっとずつ見慣れたアプリっぽくなってきました。
機能を足していってる感じがおもしろい。
次回は発展的なログイン機構ということで応用っぽいですね。がんばりましょう。

Ruby on Rails チュートリアル第7章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

第7章 ユーザー登録

さぁやってきました第7章。
もう半分なんですね。
前回はモデルの構造を色々いじってユーザーを登録できる土台をつくって、
さらにはパスワードを認証する機能も作成しました。

今回は実際にユーザー登録を行えるようにUIも含めて実装していくみたい。
がんばりましょー。

まず前段階として、ページのレイアウトにデバッグ情報を追加します。
こうすることによってどのコントローラのアクションが実行されたのかを、
ブラウザに描画されたページで確認することができます。

#application.html.erb

<!DOCTYPE html>
<html>
  .
  .
  .
  <body>
      <div class="container">
        ・
        ・
        ・
      <%= debug(params) if Rails.env.development? %> #ここを加える
    </div>
  </body>
</html>

Erbファイルに上記を加えることにより、開発環境での実行時のみデバッグ情報を確認することができます。

f:id:Npakk:20200627123738p:plain

前章でコンソールからUserを一人作成しましたが、まだアプリケーションにはそのユーザーを表示する機能はありません。
RESTアーキテクチャに従って実装します。
つまりデータの作成、表示、更新、削除をリソースとして扱えるようにします。

今はまだ、users/1というURLにアクセスしてもエラーが表示されるので、
ルートファイルに下記を追加します。

#config/routes.rb

Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  get  '/signup',  to: 'users#new'
  resources :users #ここ
end

これを追加することで、ユーザーのURLを生成するための名前付きルートと、
RESTfulなUsersリソースで必要なアクションの全てが利用できるようになるとのこと。
とりあえずルーティングはできるようになったので、次はページを作成していきます。

Railsの標準的な場所であるapp/views/users/show.html.erbにユーザー名と、メールアドレスを表示する埋め込みRubyを書きます。

#show.html.erb
<%= @user.name %>, <%= @user.email %>

上記はインスタンス変数@userがあることが前提なので、
Usersコントローラのshowアクションに、@userを定義します。

#users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id]) #ここ
  end

  def new
  end
end

このコントローラにリクエストが送信されると、params[:id]はユーザーIDの1に置き換わり、
User.find(1)を実行したときと同じになります。
実際にアクセスしてユーザー情報が表示されることを確認します。

f:id:Npakk:20200627124212p:plain

上記ではデバッグ情報を確認するためにerbファイルにデバッグコードを埋め込みましたが、
Bybugというgemを使ったデバッグ方法もあります。

#users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    debugger #ここ
  end

  def new
  end
end

上記を加えると、/users/1にアクセスしたときにコンソール上にデバッグ情報が表示されるようになります。
どう使い分けるかというところまでは言及されていませんが、byebugのほうがより手軽かと思いました。
便利なのはerb埋め込みですかね。

そしてユーザープロフィール画面の表示をもう少し肉付けするために、Gravatarというサービスを利用します。
プロフィール写真を指定したメールアドレスと関連付けすることができるのですが、
これを導入すると写真をアップロードする面倒な作業や、画像をどこに配置するかなどの悩みから解決されるとのこと。

GravatarのURLを返すメソッドをヘルパーメソッドとして用意し、それを使うようにページ画面のerbに埋め込みます。
SCSSで見た目を整えて、最終的には下記のようになりました。

f:id:Npakk:20200627124240p:plain

次はユーザー登録画面です。 form_withヘルパーメソッドをつかって、ユーザー登録に必要な情報を登録するフォームを作成します。
まずコントローラのnewアクションに@userのインスタンス変数を追加します。

#users_controller.rb
class UsersController < ApplicationController

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

  def new
    @user = User.new #ここ
  end
end

そしてユーザー登録画面にform_withヘルパーメソッドを使用したフォームを実装します。

#new.html.erb
% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_with(model: @user, local: true) do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.email_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

詳細は割愛しますが、このヘルパーメソッドを用いて、
モデルとフォームの入力内容を関連付ける働きをしてくれます。

フォームに必要な情報を入力し、submitを押下すると、/usersへPOSTリクエストが送られ、
Createアクションに伝達されます。
Createアクションを下記のように実装します。

#users_controller.rb
class UsersController < ApplicationController

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

  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])    # 実装は終わっていないことに注意!
    if @user.save
      # 保存の成功をここで扱う。
    else
      render 'new'
    end
  end
end

ここで、params[:user}と記載しておりますがここにフォームで入力した値が入ってきます。
また悪意あるユーザーにより操作から守るため、Strong Parametersというテクニックを用います。 リクエストに含まれる属性をそれぞれ許可するかどうかを設定し、
さらにそれをprivateメソッドにして外部からアクセスできないようにするんですね。
必須のテクニックそうですね。

今度はエラーメッセージ表示機能も実装しました。
パーシャルでエラーメッセージを表示するようにerbファイルを書き換えます。 これで、不正な値で登録ボタンをおすとエラーメッセージがユーザー登録画面に表示されるようになりました。

まだ現状ではユーザー登録ボタンを押下してもcreateテンプレートを用意していないため、
有効な値をフォームに入力してもエラーが表示されます。
Createテンプレートを作ってもいいが、ユーザー登録直後はプロフィールページにリダイレクトさせることに。

class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user #ここ
    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

上記で、プロフィールページにリダイレクトしているのですが、あまりよくわからないw
ここは下記のコードの意味と等価みたい。 redirect_to user_url(@user) 実際には、rails側が後者を推察して実行してくれたみたいですが、
こういうのほんとうにややこしい。
省略していくことは便利だが、慣れないうちは勝手になんかやってるとしか捉えられないですよねこれ。

完了したら、ユーザー登録失敗・成功時の総合テストを追加します。
登録リクエスト後にどのページにアクセスするかも含めて、ユーザープロフィールに関するほぼ全ての処理をカバーするようにしていきます。

また、本番環境ではユーザー登録のプロセス中、名前やメールアドレス・パスワードといったデータがネットワークで補足されないようにSSLを導入しました。

あとがき

本格的なアプリっぽくなってきました。
どんどん複雑になっていく内容で、ブログに書くのすら億劫になってきましたw
諦めずにとりあえず最後まで完走したい…

Ruby on Rails チュートリアル第6章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

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

現在のアプリケーションではユーザー登録してもその情報を保存する場所がないため、
今回はその情報を保存するためのデータ構造を作成していきます。

rails generate controller Users new

上記で、コントローラを生成できるわけですが、モデルは下記コマンドになります。

rails generate model User name:string email:string

Railsでは、コントローラー名には複数形を使い、モデル名には単数形を用いる慣習があります。
こういった点を守っておくと複数人で開発するときでも、認識齟齬が起きないのでぜひ覚えておきたいですね。

さて上記のgenerateを行うと、マイグレーションファイルが生成されるのでした。
ファイル名には生成された時間のタイムスタンプが記載されており、複数人で開発するときに競合(コンフリクト)が発生しにくい配慮がなされています。(完全になくすわけじゃない)

マイグレーション自体は、実際にデータベースに変更を加えるメソッドの集まりで、
このファイルを元にデータベースのオブジェクトを構成するわけです。

また、こうして自動生成されたマイグレーションファイルには、
指定したカラム以外にも、マジックカラムと呼ばれるレコードの登録時と更新時のタイムスタンプを値に持つカラムを自動的に加えてくれます。
このマジックカラム、筆者もSESで働いていますが、間違いなくどの案件でも使用しておりましたので、
覚えておいて損はないと思います。
いつそのレコードが登録され、更新されたかという情報は大事。

そして、このマイグレーションファイルを実行します。
すると、db/development.sqlite3というファイルが生成されます。
これがSQLiteというリレーショナルデータベースの実体なんですね。

中身を見ているとidカラムが自動的に追加されていました。
Railsがレコードを一意に識別するために追加したカラムらしい。
なんでもやってくれますなー

generateしたUserモデルのファイルを参照すると、下記のようになっています。

class User < ApplicationRecord
end

何のメソッドもないですが、ApplicationRecordを継承しています。
これによって、ApplicationRecordのもつメソッドを使うことが出来ます。 具体的には下記コマンドを使用しました。

  • new: オブジェクトの初期化
  • valid: オブジェクトの有効性mddチェック
  • save: データベースへの保存
  • create: オブジェクトの生成と保存
  • destroy: データベースから削除
  • find: データベースを検索
  • find_by: 特定の属性でデータベースを検索
  • first: データベースの最初のレコードを検索
  • all: 全てのデータベースのレコードを検索
  • update: データベースの特定レコードの値を更新

ある程度、ApplicationRecordのメソッドを確認したら、
モデルの各属性の検証のために、テストを追加します。

require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
  end
end

上記ソースで、setupメソッドを記載していますが、この処理は、
各テストが実行される直前で実行されます。
そしてNameとEmailの初期値を決定し、@userのインスタンス変数につっこんでいます。
このインスタンス変数を宣言しておくことによって、各テスト内で使えるようになります。
各テストでは、nameとEmail属性の存在性、一意性、書式などのテストを追加していきます。

一意性の検証では、かなり多くのことを実装しないとその一意性を担保できません。
大文字小文字を区別せずに一意性の検証を行うため、下記のコードを追記します。

#user_test.rb

  test "email addresses should be unique" do
    duplicate_user = @user.dup
    duplicate_user.email = @user.email.upcase
    @user.save
    assert_not duplicate_user.valid?
  end

@user.dupで同じ属性をもつデータを複製しています。
また、複製されたデータのemail属性に、元データのemailを大文字に変換した値を設定します。
これによって、小文字の値がきても大文字したテストが行えます。
ただし、この時点ではまたvalidメソッドは大文字小文字を区別しています。
モデルのvalidateを変更する必要があります。

#model/user.rb

class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
end

uniqueness: { case_sensitive: false }で、大文字小文字を区別せずに一意性の検証が行えます。

これで完成かと思いきや、ActiveRecordはデータベースのレベルでは一意性を保証できないらしい。
登録ボタンを2回連続で押してしまった場合、2つリクエストがサーバーに到達しますが、
どちらのリクエストにおいてもメモリー上に検証をパスするレコードが保存されます。
これを避けるためにデータベースの特定属性へインデックスを追加する必要があります。
また、インデックスを追加することによって検索の効率が上がるので一石二鳥。

次に、セキュアなパスワード認証機能を追加します。 ここはかなりむずかしいのですが、要するに
登録時にハッシュ化(不可逆なデータに変換する処理)したパスワードをデータベースに保存できるようにし、
ログイン時にユーザーから入力されたパスワードと一致するか検証したいと。

まずは、モデルにhas_secure_passwordというメソッドを追加します。 こいつのメリットは以下。

  • セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
  • 2つのペアの仮想的な属性(passwordpassword_confirmation)が使えるようになる。
    また、存在性と値が一致するかどうかのバリデーションも追加される。
  • authenticateメソッドが使えるようになる(引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド)。

ただしこいつを利用するにはモデルにpassword_digestという属性が含まれている必要があります。
ハッシュ化したパスワードを保存する受け皿が必要ということですね。
また、ハッシュ化を行うbcryptというgemをアプリに導入する必要があります。

実装後はコンソール上で仮ユーザーを作成しデータベースに保存して、has_secure_passwordのauthencticateメソッドを使って、
ハッシュ化したパスワードと引数で渡したパスワードが一致するか確認します。
無事にパスワードの一致が確認できたところで、終了。

あとがき

仕事が忙しく時間取れていないのもあると思いますが、だんだん難易度あがってきて効率も落ちて吐きそう。
インプットしつつブログでアウトプットしてますが、次々に新しい用語が出てくるので、理解が追いつかない。
地道に進めてますが、実際に自分でアプリを作ってみないと完全には身につかなさそうですねー。

Ruby on Rails チュートリアル第5章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

第5章 レイアウトを作成する

今回はサンプルアプリケーションにレイアウト・スタイルを追加して見栄えをよくしていきます。
Bootstrapというフレームワークを組み込むみたいで、それを前提にHTML要素を追加します。
Bootstrapは聞いたことはあるのですが、使用するのは今回が初めてです。

nav要素、div要素、img要素などを追加して、Rubyの埋め込みソースの説明が続きます。
HTML要素に全て変換されるので、実行してどんなものが生成されるのか確認してみるといいですね。

ひとつ面白いと思ったのは、Railsはアセットパイプラインという機能を利用して、
画像などをHTMLに表示してくれるのですが、そのときに高速化を施してくれるらしい。

画像自体は、app/assets/imagesディレクトリに保存しているのですが、
アセットパイプラインを利用して書き出されたHTMLを見てみると、assetsディレクトリに保存されているようにリンクが張られているんですよ。
もちろん裏の処理で本来のディレクトリに紐付けているのですが、こういったフラットなディレクトリ構成にすることによって、より早くブラウザに表示できるみたい。
HTML自体を書くことはこれまでもあったのですが、いやー知りませんでした。 Railsとは関係なくこうすることによって早くなるのかな、どうなんだろ。

いくつかBootstrapで利用するCSSクラスを適用したHTML要素を配置したら、
RailsアプリケーションにBootstrapのgemを組み込みます。
BootstrapではLESS CSS言語を使用しているのですが、Railsのアセットパイプライン機能はデフォルトではSass言語をサポートしています。
どちらかに合わせる必要があるため、Bootstrap-sassというLESSをSassへ変換するgemを利用することにします。

これで環境的にはSass言語で統一されます。 ただし、Sass言語には2つの記法(書き方)があります。
SASS記法と、SCSS記法です。
どちらを使ってもいいのですが、筆者はSCSS記法のほうが、波括弧でCSSを括れる点が視覚的にわかりやすいので好きです。

またRailsのビューは、ERBファイルと1:1の関係というわけではなく、パーシャルという機能をつかって、
1つのビューファイルに他のERBファイルを埋め込むことが可能です。 別管理したい情報などはこの機能を使って、ファイルを分けていると修正時の影響範囲が少なくなるので、
どんどん使った方がいいと思います。

アセットパイプラインの他の機能

上記で少し紹介したアセットパイプラインですが、他にも機能があります。

アセットパイプラインでは、アセットディレクトと呼ばれるデフォルトのディレクトリにある静的ファイルを目的別に分類して利用しています。

  • app/assets:現在のアプリケーション固有のアセット
  • lib/assets:ライブラリ用のアセット
  • vendor/assets:サードパーティ用のアセット

それぞれのアセットを分類して配置してあげるのですが、このディレクトリにはサブディレクトリも存在します。

  • config
  • images
  • stylesheets

画像ならimages、CSSならstylesheetsに保存してあげるわけですね。

また、これらに配置した静的ファイルをどのように一つにまとめるかをRailsに指示するためにマニフェストファイルを利用します。 実際にまとめるのはSprocketsというgemですが、これを利用することによってひとつの静的ファイルの塊にどの要素を加えるのかを決定することができます。

様々なアセットをアセットディレクトリに配置し、プリプロセッサエンジンによって実行され、
ブラウザに配信できるようにマニフェストファイルに沿って結合され、テンプレート用に準備されます。
どのプリプロセッサエンジンを使って実行するかは拡張子によって、Railsが判断してくれます。

つまるところ、アセットパイプラインのすごいところは、
開発環境では複数あるCSSファイルを本番環境ではひとつにまとめてくれて、かつ圧縮も行ってくれるところです。
これによって高速化を図ってくれます。
圧縮された場合は見にくくなるのですが、開発者がみるときは圧縮前のファイルを見れるわけですから、
かなり便利な機能なわけです。

さて、今までつくったアプリではここのページへのアクセスを下記のURLでアクセスしていました。
/コントローラー名/help

少し省略して下記のように変更します。
/help

これを実現するにはルートファイルを編集します。

#get 'static_pages/help'
get '/help', to:'static_pages#help'

上記の変更を加えることによって、GETリクエストが/helpに送信されたときに、
コントローラーのhelpアクションを呼び出してくれます。 また、同時に名前付きルートを使用できるようになります。

そして、統合テストについても軽く学びました。
ブラウザによるページ間の遷移をもシミュレートすることができ、
これまでは特定ページが応答を返すかどうかだけだったテストが、複数ページ間で正しく遷移されるのかという点をもテストすることができます。
またページ中に特定のhtml要素が存在するかどうかもテストできるようになります。

あとがき

4章もむずかしかったですが、5章ではすでに作成しているアプリケーションを効率的にするために、
修正を加えていくためより難しい印象でした。
残り9章と先は長いですが、がんばります。

Ruby on Rails チュートリアル第4章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

第4章 Rails風味のRuby

前回、重複コードを排除するため埋め込み型のRubyコードをHTML形式に記載しましたが、
今度は新しく自分で定義した関数を使ってみます。
”カスタムヘルパー”と呼ぶらしい。
ここでは値がAだったらBだったらと条件分岐も行える関数を作成して、
組み込みヘルパー(Rails標準で用意されている関数)から自作のカスタムヘルパーへ変更していきます。

完成したら今度はRubyの言語仕様を学ぶため、Railsコンソールを使用します。
対話的にRubyを操作できるみたい。
この中での操作は基本的に外に影響を与えることはなく、もし異常が発生してもコンソール自体を終了すれば大丈夫とのこと。
また、記述されているRubyコードで気になったものがあれば、RubyAPIを併せて読むと理解しやすくなるらしい。
ただ、英語なので日本語が母語の方は下記で代用してください、とのこと。
ざっと見た感じRuby言語のバージョンごとにリファレンスがあって、便利そう。
プログラミング言語 Ruby リファレンスマニュアル
るりまサーチ

まずは文字列から勉強。
ダブルクオートを用いたリテラル文字列をコンソールに入力すると、ダブルクオートの中の文字列だけが応答として返ってきます。
また、文字列同士をプラス(+)でくっつけると文字列結合が行え、
さらに、式展開を使って文字列の変数と文字列の結合も行いました。

ちなみにダブルクオートで文字列をくくらず、シングルクオートでもくくれるが、上記の式展開は行われません。
シングルクオートの利点としては、”/”や”#”などの特殊文字エスケープ処理せずに出力できる点にあるみたい。
ダブルクオートで同じことをしようとすると、明示的にエスケープ処理を行う必要があるため、めんどくさいらしい。

今度は様々なオブジェクトとその操作を学んでいきます。
数値型を文字列として出力したり、真偽値を駆使して応答値をそれぞれ変更するやり方などを学びます。
なお、Javaなどではオブジェクトの空を表すのは”null”でしたが、Rubyでは”nil”なんですね。
呼び方が似ているため意味も同じだと思うのですが、どういった違いがあるのだろうか。

また関数の作成もコンソール上ではめんどくさいんですが行います。
関数定義→利用→戻り値確認していくのですが、
驚いたのは”暗黙の戻り値”という仕様。

def isEmpty(str)
    return “A” if str.empty?
    return “B”
end

上記のような、rubyの関数があった場合、
後ろにある「return “B”」の「return」はなくてもいいんです。
JavaC#では、ここらへんは静的解析でreturnしろと警告されるのですが、
Rubyは仕様上、明示的にreturnされた戻り値か、 最後に記述された式を戻り値として呼出元に返すみたい。
もし、最後に記述された式が戻り値を表すものではない場合、もしくはそもそも式が記述されていない場合は、
Nilを返却するらしい。
面白いですねー

また、配列についても学びました。
この仕様は他のほとんどの言語と似たようなものなのですが、
”破壊的メソッド”なるものがRubyメソッドには存在します。 a.sort などと記述すると配列の中身をソートした結果を返してくれるのですが、
このa自体の中身は変わらないと。
ただ感嘆符(!)をつけることによって破壊的メソッドに変わり、
aの中身が変わります。
a.sort!

お次は範囲(Range)。
配列の添え字の指定方法や、数値、アルファベットの範囲指定を学びます。
ここは他の言語(私が経験あるのはC#Java)と比較しても、癖が強すぎました。
ただ便利なのは確かです。
記述量があきらかに減らせるケースがあります。
しかし、あまりに見慣れない記法なので、ぱっと見なにをやっているのかわからなかったです←

そしてブロック。
記法は見慣れないためぱっと見わからないですが、じっくり読んでもさっぱりわかりませんw
最初は他言語でのfor文の書き方っぽいものと思っていましたが、調べてみると色んな使い方がありました。
つまるところ引数の一つとして解釈したほうがわかりやすくて、
関数に渡す引数の最後として記述しなくてはいけないみたい。
ブロック引数と呼ばれていたのでそちらの認識で思っておいて、ブロック内にある一時的な変数がありますが( | | で囲んでるもの)これはブロック変数と呼ばれるもの。
ローカルな変数であり外からは参照できません。
難しいですね

そしてクラスの作成方法と、組み込みクラスの変更、継承について学びました。
ここらへんは他言語経験者であればすんなり理解できるかと思います。
ただ一点気になったのは本文中でも触れられているのですが、コントローラクラスのアクションたちが、
def で定義されているんですが、その中身は何も記述されていないのです。
なのに、ルーティングされた場合ページが表示されるんですよ。
うーんいつか触れてくれるのでしょうか…

あとがき

今回はRubyの言語仕様がメインでした。
サンプルアプリケーションのこれまでの実装を見ながら、Rubyの説明をする流れなので、
ある程度最初に疑問をもっておくと伏線回収的なもんであーっと理解出来るかも知れません。
ただ、この4章はかなり長いので、挫折しないようにわからなくても先に進むことも必要かも知れませんね。

Ruby on Rails チュートリアル第3章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

第3章 ほぼ静的なページの作成

これまでと同じくgemファイルを編集し、必要なgemをインストール後、
GitHub・Herokuへのプッシュ・デプロイを先に実行。
前回は、scaffoldを使用して簡単にモデル・コントローラ・ビュー・ルーティングの全てを自動設定しましたが、今回から個別に作成していき、railsの概要をつかんでいくらしい。

Generateスクリプトを使用してコントローラを生成すると、config/routes.rbファイルが自動更新され、
URLにアクセスしたときに対応するアクションを呼び出す対応関係が作られる。
またこのGenerateスクリプトで自動生成されたソースは、Destoryスクリプトで元に戻せるらしく、
コントローラとモデルとマイグレーションのそれぞれで使えるらしい。
使うことはあるのかなー

コントローラー

$ rails generate controller StaticPages home help
$ rails destroy controller StaticPages home help

モデル

$ rails generate model User  name:string email:string
$ rails destroy model User

マイグレーション

$ rails db:migrate
$ rails db:rollback
$ rails db:migrate VERSION=0

マイグレーションは逐次的に実行され、それぞれバージョン番号が付与される。
そのため、0を指定した数値に置き換えると、そのバージョンに戻すことができる。

そして、新たにGenerateスクリプトでページを追加する前に、テスト駆動開発を導入するとのこと。
メリット・デメリットあるみたいですが、主なメリットは以下。

  • 機能追加の副作用としてバグを生んでしまうことを防ぐ
  • 機能を変更せずコード整形(リファクタリング)を安全に行える。
  • アプリケーションの設計や他システムとのインターフェイスを決めやすい。

精神衛生上、バグってんじゃねーかなって状態で機能追加するのは集中力も削がれるので、
こういった自動テストの仕組みがあるのは有り難い。
なんでもかんでもテストすればいいってもんではないみたいですが。

そしてこの自動テストの実装は、Generateスクリプトを実行した際に自動で行われているみたいで、
いくつかテストコードが生成されておりました。
これに追加のテストコードを実装します。
応答が返ってくるか、htmlの特定タグの中身は指定した形式で出力されているか、など簡単な内容を追加していく。
複雑なアプリのテストコードを見てみたいですねー、実装しているコードと同じくらい記述してそうな気がします。

ある程度テストコードを追加したら、ソースの記載が重複している箇所を修正していきます。
DRY原則(Don’t Repeat Yourself: 繰り返すべからず)という原則に従う必要があるため、
こういった重複は排除するとのこと。
つまり、同じコードは書くなってことですね。
HTML形式のテンプレートファイルに、ERBという埋め込み型のRubyコードを書いて、繰り返し処理などを駆使して記述箇所が重複している箇所を修正していきます。

最後に、Guardというgemを使って特定ファイル編集時に自動的にテストを行う方法を学びました。
Guradfileに必要な動作を記述し、実行すると例えばルーティングファイルを変更したときだけ、
テストを実行することができました。
実行する手間も省けます。

あとがき

なぜそうしないといけないのかという部分も説明してくれるので、理解がしやすいです。
忙しくなってきてあまり時間がとれていませんが、もっと時間を捻出してさらに理解を深めていきたい。

Ruby on Rails チュートリアル第2章を終えて

f:id:Npakk:20200610222322p:plain

はじめに

このエントリーでは、Railsを勉強している私がRuby on Rails チュートリアルを学習した感想などを、
各章毎に述べていきたいと思います。
このチュートリアルを学ぶ方法は動画、電子書籍など色々な媒体で提供されておりますが、
ここではWebテキスト(第6版)を使用しております。

目次

第2章 Toyアプリケーション

Scaffoldジェネレータというスクリプトを使って、おもちゃアプリケーションを作ろうという内容。 Railsの用語や、エンジニア用語などが少し増えてくる。 自分なりに調べてこういった用語を解説しているが、 多少ではなくかなり間違っている可能性もあるので、ご指摘あればよろしくお願いします。

Scaffold

コントローラ・モデル・ビュー・ルーティングの全てを自動生成してくれる機能で、
好きなデータ型を指定すればString型だったりInteger型のメンバーを持つモデルを生成してくれるし、
そのデータ型で構成されるモデルの新規作成、修正、削除、一覧などのリクエスト応答処理も自動で生成してくれる。 Scaffold=”足場”の意味。
Railsの細かな仕様を理解するのには向いていないため、初心者は注意しようとのこと。
この機能の動きを把握しているなら、自動生成してくれるわけだし大変便利だと思う。

マイグレーション

Scaffoldを実行した後は、マイグレーションを行い、ユーザーから送られたデータをDBに登録できるようにする必要がある。
DBを直接操作してテーブルを作成する場合、SQLを使う必要があるが、
このマイグレーション機能を使えば、マイグレーションファイルを元に、 テーブルをRuby側で操作することが可能になる。
実はScaffoldでモデル作成時にマイグレーションファイルも作成されており、下記コマンドを実行すれば、 マイグレーション機能が働き、モデルを元にしたテーブル構造をDBに作成・反映してくれる。

$ rails db:migrate

Scaffoldで生成したビューを介して、ユーザーの登録・更新・削除を行う。 自動生成されたHTMLテンプレートを用いているため表示は非常に簡素だが、登録したデータなどがちゃんと反映されるのを見ると改めてすごい機能だと実感しました。

また、リクエストを受けてから内部ではどのように動いているのかをMVCパターンの観点から紐解いていくので、
ひとつひとつ手順を確認してMVCパターンの概要を知るといいですね。

そしてRailsにおけるRESTアーキテクチャにも触れていきます。

REST

REpresentational State Transferの略で、分散型システムにおける複数のソフトウェアを連携させるのに適した設計原則の集合、考え方のこと。 Railsはこの原則に従って設計されており、作成すべきコントローラやアクションがシンプルになりシステム規模の拡大などにも容易に対応可能になる。

ユーザーのデータモデルを作成したあとは、同じようにマイクロポスト(短い投稿の意味)のデータモデルを作成。
140文字まで入力可能・入力必須など、制限を追加しながら実装していきました。
また、データモデル同士の関連付けやクラス継承についても学習しました。

あとがき

用語なども増えてきて、複雑になってきたという印象。
逐一わからないところは調べないとチュートリアルでは全てを説明してくれているわけではないので、 見失う可能性が高いと感じました。
まだまだ第2章なのでがんばりたいですね。