#目次
#1. はじめに
- この記事は、Rails初学者の工業大学三年生がRailsチュートリアルの学習記録を
つけるための記事です。 - 筆者自体がRailsやWebについて知識が少ないので、内容の解釈などに
間違いがある可能性があります。(その時はコメントで指摘してくださると助かります!) - Railsチュートリアル内ではRailsの内容以外にも、gitでのバージョン管理やHerokuを使ったデプロイも
学習しますが、gitに関しては既に私が学習済みのため学習記録には記述しません。 - 演習の記録も省略します。
#2. 第3章の概要
この章ではRailsを扱う上で重要なRubyの要素について学習します。
アプリケーションへの変更はあまり多くなく、どちらかというとRubyの言語仕様をRails consoleを使用して
学ぶことが中心だったので、その内容は私が初めて知った内容や後から見返せるようにしたい内容のみを記述していきます。
- カスタムヘルパーの定義
- カスタムヘルパーとは
- タイトルが未定義だった場合の動作を定義する
- Rails風味のRuby
- クラスを定義する
#3. 学習内容
###1. カスタムヘルパーの定義
####1-1. カスタムヘルパーとは
カスタムヘルパーとは、ビュー内で使用する関数の内、開発者自身で新しく作成した関数のことです。
Railsによって自動的に作成される関数は組み込み関数と呼ばれます。
カスタムヘルパーは、コントローラの作成時に同時に作成されるヘルパーファイルに記述していきます。
####1-2. タイトルが未定義だった場合の動作を定義する
ここで定義するカスタムヘルパーは、タイトルが定義されていないときに、
表示されるタイトルを変えるカスタムヘルパーです。
第3章で、それぞれのページごとに自動的にタイトルが変わるようにビューの設定を行いました。
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</p>
前回、変更を加えたビューの1つです。
最初の行の<% provide(:title, "Home") %>
で、ビューのタイトルを定義し、application.html.erbというファイルで
その値を受け取ることで「Home | Ruby on Rails Tutorial Sample App」というタイトルを表示しています。
しかし、もしビューファイルにタイトルの定義が無ければ
「| Ruby on Rails Tutorial Sample App」というタイトルになってしまいます。
余分な縦棒(|)が初めに表示されてしまうため、カスタムヘルパーによってタイトルが定義されていないときは、
縦棒なしの「Ruby on Rails Tutorial Sample App」というタイトルが表示されるようにします。
カスタムヘルパーの名前はfull_titleと定義して、内容は以下のコードを使用して説明します。
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
このカスタムヘルパーはデフォルト値がnilの引数を1つ取ります。
この引数はページごとのタイトルと対応してif page_title.empty?
で条件分岐に利用されます。
この条件式がtrueだった場合、つまりページごとのタイトルが定義されていない場合に、
base_titleという変数を返します。
base_titleの内容は「Ruby on Rails Tutorial Sample App」という文字列です。
そして、条件式がfalseだった場合、つまりページごとのタイトルが定義されている場合には、
ページごとのタイトル、縦棒(|)、Ruby on Rails Tutorial Sample Appの3つの文字列が結合された文字列が返されます。
このヘルパーを作成すればapplication.html.erbのtitleタグを書き換えることができます。
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
から、
<title><%= full_title(yield(:title)) %></title>
というコードになります。
変更後では、各ビューのタイトルが引数として渡されています。
###2. Rails風味のRuby
ここでは、Rubyの言語仕様やメソッドの使用方法について初めて知ったことや、
見返せるように記録しておきたいと思ったものを書いていきます。
①「後置 if」でif文を一行で書く
if文は通常、以下のように最低でも3行必要です。
if 条件式
処理
end
しかし、Rubyの後置ifというものを使えば、処理が1行のみの場合にif文を1行で書くことができます。
処理 if 条件式
このように記述すると条件式がtrueの時のみ処理が実行されます。
後置ifは便利ですが返り値が特殊らしいので注意が必要らしいです。
参考:【Ruby】後置ifが末尾にあるメソッドの返り値はなに...?
②範囲オブジェクトの対応範囲
範囲オブジェクトとは1..10と記述することで生成される順番に値が取得できるオブジェクトです。
上記の場合1~10の整数が1つずつ取得できます。
この範囲オブジェクトは文字にも対応しており、
"a".."g"や、"あ".."お"、"一".."九"などでもオブジェクトが生成されました。内容は以下の通りです。
・('a'..'g').to_a
=> ["a", "b", "c", "d", "e", "f", "g"]
・('あ'..'お').to_a
=> ["あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お"]
・('一'..'九').to_a
["一", "丁", "丂", "七", "丄", "丅", "丆", "万", "丈", "三", "上", "下", "丌", "不", "与", "丏", "丐", "丑", "丒", "专", "且", "丕", "世", "丗", "丘", "丙", "业", "丛", "东", "丝", "丞", "丟", "丠", "両", "丢", "丣", "两", "严", "並", "丧", "丨", "丩", "个", "丫", "丬", "中", "丮", "丯", "丰", "丱", "串", "丳", " 临", "丵", "丶", "丷", "丸", "丹", "为", "主", "丼", "丽", "举", "丿", "乀", "乁", "乂", "乃", "乄", "久", "乆", "乇", "么", "义", "乊", "之", "乌", "乍", "乎", "乏", "乐", "乑", "乒", "乓", "乔", "乕", "乖", "乗", "乘", "乙", "乚", "乛", "乜", "九"]
漢数字で1~9が取得できるかと思ったら、辞書順?で漢字が取得できました。
③ブロックとは
ブロックとは配列や範囲の値を1つずつ取得して、処理を行う仕組みです。
>> (1..5).each { |i| puts 2 * i }
2
4
6
8
10
上のコードは1~5の整数を1つずつ取り出して i に代入、そして i を2倍した値を出力しています。
この i のことをブロック変数と呼びます。
④ハッシュとシンボル
ハッシュとは配列と似たオブジェクトで、キーと値がペアになったものです。
ハッシュを定義するときの書き方にはリテラル表現を使用した書き方と、シンボルを使用した書き方があります。
・リテラル表現を使用した書き方
user = { "first_name" => "Michael", "last_name" => "Hartl" }
{"last_name"=>"Hartl", "first_name"=>"Michael"} #結果
・シンボルを使用した書き方
user = { :first_name=>"Michael", :last_name=>"Hartl" }
{ :first_name=>"Michael", :last_name=>"Hartl" } #結果
#シンボルは以下のように書くこともできる
user = { first_name: "Michael", last_name: "Hartl" }
{ :first_name=>"Michael", :last_name=>"Hartl" } #結果
リテラル表現ではハッシュロケットという=>を使ってキーと値を記述します。左辺がキー、右辺が対応する値です。
シンボルを使用した表記方法は、コロンをシンボル名の前においてハッシュロケットを使用する書き方と、
シンボル名の後にコロンをおく書き方があります。
⑤Rubyにおける関数の書き方
ここではサンプルアプリケーションのレイアウトファイルの以下の一文を用いて、Ruby特有の関数の書き方を説明します。
<%= stylesheet_link_tag 'application', media: 'all',
'data-turbolinks-track': 'reload' %>
このコードはスタイルシートを追加する「stylesheet_link_tag」というメソッドですが、書き方がRuby特有です。
1つ目のポイントは引数の丸カッコがありません。
Rubyではメソッド呼び出しの丸カッコを省略できます。
2つ目のポイントは2つ目の引数のmedia: 'all', 'data-turbolinks-track': 'reload'
という部分です。
この引数はハッシュですがハッシュを表す波カッコがありません。
Rubyではハッシュが最後の引数であれば、波カッコを省略できます。
3つ目のポイントは途中に開業が含まれている点です。
Rubyは開業と空白を区別しないため、コードの途中での改行時に折り返し用の文字列を入れる必要がありません。
以上のポイントをまとめると、最初のコードは以下の全てのコードと等価と言えます。
# 元のコード
stylesheet_link_tag 'application', media: 'all',
'data-turbolinks-track': 'reload'
# 丸カッコあり
stylesheet_link_tag('application', media: 'all',
'data-turbolinks-track': 'reload')
# 波カッコあり
stylesheet_link_tag 'application', { media: 'all',
'data-turbolinks-track': 'reload' }
# 改行なし
stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
# 省略、改行なし
stylesheet_link_tag('application', { media: 'all', 'data-turbolinks-track': 'reload' })
###3. クラスの作成方法
Rubyではあらゆるものがオブジェクトであり、何らかのクラスに属しています。
それぞれのクラスの継承関係はsuperclassメソッドで確認できます。
ここでは自分でクラス定義のこーどについて説明します。
ここで定義するUserクラスはこの章でしか使用しないので、ルートディレクトリ直下に「examole_user.rb」というファイルを作成します。
クラス定義のコードを以下に示します。
class User
attr_accessor :name, :email
def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end
def formatted_email
"#{@name} <#{@email}>"
end
end
まず、class クラス名
でクラス名を定義します。この時クラス名の頭文字は大文字にします。
その次のattr_accessor
ではnameとemailという2つの属性に対応するアクセサーを作成しています。
アクセサーが作成されるとインスタンス変数が使用できるようになります。
つまり、@name, @emailという2つのインスタンス変数をクラスメソッドやビューで使用できるようになるということです。
その下のdefで始まる2つの文がクラスメソッドです。
1つ目のクラスメソッドはRubyの特殊なメソッドで、User.newを実行してインスタンスを作成すると
自動的に実行されるメソッドです。
このメソッドはattributesという空のハッシュを引数として持ちます。
よって、User.newを実行したときに:name. :emailとラベルを指定して値を渡すと、
userインスタンスのインスタンス変数に初期値として入力されます。
また、User.newを実行したときに値を渡さないと初期値はnilとなります。
formatted_emailというクラスメソッドはRailsチュートリアルないで学習のために作成したメソッドで、
名前とメールアドレスを式展開を使用してユーザ名とメールアドレスを一緒に返すメソッドです。
#4. 終わりに
第4章では、Rubyの言語仕様を中心に学習しました。
私はRubyはProgateくらいでしか学んでいないので知らないことがまだ多く、抽象的な概念に関しては
Rubyのコードを書いた経験が少ないゆえに理解が浅い状態です。
これ以降アプリケーションの機能の追加やテストの実装を行っていくので、
意味が理解できないコードは一つ一つリファレンスマニュアルを参照して、時間をかけてでも理解しながら進めていこうと思います。