Rails Tutorial、始めました【4章】
Rails Tutorial 4章に突入!
3章の記事はこちらから↓
Rails Tutorial、始めました【3章】
4章 Rails風味のRuby
今回はRubyの文法学ぼうの回でした。
ほとんどコードをまとめるだけになるかも^^;
カスタムヘルパー
Railsのビューで使う組み込み関数は、自分で作ることもできるようです。
1 2 3 4 5 6 7 |
<% 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 2 3 4 5 6 7 8 9 10 11 12 |
<span class="k">module</span> <span class="nn">ApplicationHelper</span> <span class="c1"># ページごとの完全なタイトルを返します。</span> <span class="k">def</span> <span class="nf">full_title</span><span class="p">(</span><span class="n">page_title</span> <span class="o">=</span> <span class="s1">''</span><span class="p">)</span> <span class="n">base_title</span> <span class="o">=</span> <span class="s2">"Ruby on Rails Tutorial Sample App"</span> <span class="k">if</span> <span class="n">page_title</span><span class="o">.</span><span class="n">empty?</span> <span class="n">base_title</span> <span class="k">else</span> <span class="n">page_title</span> <span class="o">+</span> <span class="s2">" | "</span> <span class="o">+</span> <span class="n">base_title</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span> |
Viewにあるコードに下記の変更を加えれば、full_title関数が使われるようになります。
また、privideの行はいらなくなったので削除してOKです。
テストには下記のコードを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
require 'test_helper' class StaticPagesControllerTest < ActionDispatch::IntegrationTest test "should get home" do get static_pages_home_url assert_response :success assert_select "title", "Ruby on Rails Tutorial Sample App" # 追加 end test "should get help" do get static_pages_help_url assert_response :success assert_select "title", "Help | Ruby on Rails Tutorial Sample App" end test "should get about" do get static_pages_about_url assert_response :success assert_select "title", "About | Ruby on Rails Tutorial Sample App" end end |
文字列とメソッド
ここはRubyの基本的な知識を学びましょうって感じでしたね。
一応やったことをまとめますが、あんまりRailsは関係なかったです。
文字列
文字列についてですね。
書いて合ったことを下記にまとめました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ rails console >> "foo" + "bar" #文字列の結合 => "foobar" >>first_name = "Taro" >>last_name = "Yamada" >> "#{first_name} #{last_name}" #文字列の式展開 => "Taro Yamada" >> first_name + " " + last_name #式展開を使わない場合 => "Tarp Yamada" >> puts "foo" # 文字列を出力する foo => nil >> print "foo" # 文字列の画面出力 (putsと同じだが改行がない) foo=> nil >> print "foo\n" # puts "foo" と等価 foo => nil >> '#{foo} bar' # シングルクォート内の文字列では式展開ができない => "\#{foo} bar" |
オブジェクトとメッセージ受け渡し
Rubyではあらゆるものがオブジェクトです!という説明が書いてありました。
例えば文字列とかnilとか、””までもがオブジェクトです!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
>> "foobar".length # 文字列に "length" というメッセージを送る => 6 >> "foobar".empty? => false >> "".empty? => true >> nil.to_s => "" >>nil.empty? NoMethodError: undefined method 'empty?' for nil:NilClass >> nil.to_s.empty #メソッドを2つ以上繋げることをメソッドチェーンという => true >> "foo".nil? => false >> "".nil? => false >> nil.nil? => true >> !!nil #!を2つ繋げると、オブジェクトそのものを論理値に変換できる。「!!」(バンバン)と呼ぶ。 => false |
メソッドの定義
自分でメソッドを作ってみようの回です。ここも特に特筆すべきことはないですかね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
>> def string_message(str = '') >> if str.empty? >> "It's an empty string!" >> else >> "The string is nonempty." >> end >> end => :string_message >> puts string_message("foobar") The string is nonempty. >> puts string_message("") It's an empty string! >> puts string_message It's an empty string! >> def string_message(the_function_argument = '') #引数名は自由 >> if the_function_argument.empty? >> "It's an empty string!" >> else >> "The string is nonempty." >> end >> end => :string_message >> puts string_message("") It's an empty string! >> puts string_message("foobar") The string is nonempty. |
他のデータ構造
配列と演算子
配列について学びます。結構色々ありました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
>> "foo bar baz".split # 文字列を3つの要素を持つ配列に分割する => ["foo", "bar", "baz"] # 配列にアクセス >> a = [42, 8, 17] => [42, 8, 17] >> a[0] # Rubyでは角カッコで配列にアクセスする => 42 >> a[1] => 8 >> a[2] => 17 >> a[-1] # 配列の添字はマイナスにもなれる! => 17 # 番号を使わずに配列にアクセス >> a # 配列「a」の内容を確認する => [42, 8, 17] >> a.first => 42 >> a.second => 8 >> a.last => 17 >> a.last == a[-1] # == を使って比較する => true >> x = a.length # 配列も文字列と同様lengthメソッドに応答する => 3 #様々なメソッド >> a => [42, 8, 17] >> a.empty? => false >> a.include?(42) => true >> a.sort => [8, 17, 42] >> a.reverse => [17, 8, 42] >> a.shuffle => [17, 42, 8] >> a => [42, 8, 17] # 配列に値を追加する >> a.push(6) => [42, 8, 17, 6] >> a << 7 => [42, 8, 17, 6, 7] >> a << "foo" << "bar" #2つを一気に追加 => [42, 8, 17, 6, 7, "foo", "bar"] # 配列から範囲指定で取り出す >> a = %w[foo bar baz quux] # %wを使って文字列の配列に変換 => ["foo", "bar", "baz", "quux"] >> a[0..2] => ["foo", "bar", "baz"] |
ブロック
Rubyの極めて強力かつ分かりにくい機能です。
each、times、mapを学びました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#each >> (1..5).each do |i| ?> puts 2 * i >> end 2 4 6 8 10 => 1..5 >> (1..5).each do |number| ?> puts 2 * number >> puts '--' >> end 2 -- 4 -- 6 -- 8 -- 10 -- => 1..5 # times >> 3.times { puts "Betelgeuse!" } # 3.timesではブロックに変数を使っていない "Betelgeuse!" "Betelgeuse!" "Betelgeuse!" => 3 # map >> (1..5).map { |i| i**2 } # 「**」記法は冪乗 (べき乗) => [1, 4, 9, 16, 25] >> %w[a b c] # %w で文字列の配列を作成 => ["a", "b", "c"] >> %w[a b c].map { |char| char.upcase } => ["A", "B", "C"] >> %w[A B C].map { |char| char.downcase } => ["a", "b", "c"] |
ハッシュとシンボル
ハッシュは整数値以外のものをインデックスにつける点だけ、配列と異なります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
>> user = {} => {} >> user["first_name"] = "Michael" => "Michael" >> user["last_name"] = "Hartl" => "Hartl" >> user["first_name"] => "Michael" >> user => {"last_name"=>"Hartl", "first_name"=>"Michael"} #ハッシュのキーとしてシンボルを使う場合 >> user = { :name => "Michael Hartl", :email => "michael@example.com" } => {:name=>"Michael Hartl", :email=>"michael@example.com"} >> user = { name: => "Michael Hartl", email: => "michael@example.com" } #どちらも同じ意味 => {:name=>"Michael Hartl", :email=>"michael@example.com"} >> user[:name] => "Michael Hartl" >> user[:password] => nil >> flash = { success: "It worked!", danger: "It failed." } => {:success=>"It worked!", :danger=>"It failed."} >> flash.each do |key, value| ?> puts "Key #{key.inspect} has value #{value.inspect}" >> end Key :success has value "It worked!" Key :danger has value "It failed." #ハッシュでもeachメソッドが使える >> flash = { success: "It worked!", danger: "It failed." } => {:success=>"It worked!", :danger=>"It failed."} >> flash.each do |key, value| ?> puts "Key #{key.inspect} has value #{value.inspect}" >> end Key :success has value "It worked!" Key :danger has value "It failed." #inspectメソッドでは、要求されたオブジェクトを表す文字列を返す >> puts (1..5).to_a.inspect # 配列のリテラルを出力 [1, 2, 3, 4, 5] >> puts :name, :name.inspect name :name >> puts "It worked!", "It worked!".inspect It worked! "It worked!" |
CSS、再び
タイトルはすごいですが、CSSはかっこ、改行の有り無しは関係ないんだぜ!プログラマーの思い通りだ。すごいだろ?
ってのが書いてあるだけでした。以下のような感じですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<%= 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' |
Rubyにおけるクラス
ついにクラスきたか!Rubyでは全てがオブジェクトですからね。クラスはしっかり分かっとかないとダメですよね。
コンストラクタ
まずはコンストラクタです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
>> s = "foobar" => "foobar" >> s.class ただの文字列でさえStringクラス => String #クラスなので、以下のような書き方もできる >> s = String.new("foobar") => "foobar" >> s.class => String >> s == "foobar" => true #配列も同様 >> a = Array.new([1, 3, 2]) => [1, 3, 2] #ハッシュは、デフォルト値を引数にとる >> h = Hash.new => {} >> h[:foo] # 存在しないキー (:foo) の値にアクセスしてみる => nil >> h = Hash.new(0) # 存在しないキーのデフォルト値をnilから0にする => {} >> h[:foo] => 0 |
クラス継承
Javaではよく聞くクラス継承ですが、Rubyにもあるんですね。うまく使ったら便利そうだな〜と思うけど、私は全然使いこなせないです(^_^;)
1 2 3 4 5 6 7 8 9 10 |
>> s = String.new("foobar") => "foobar" >> s.class # 変数sのクラスを調べる => String >> s.class.superclass # Stringクラスの親クラスを調べる => Object >> s.class.superclass.superclass # Ruby 1.9からBasicObjectが導入 => BasicObject >> s.class.superclass.superclass.superclass => nil |
ふむふむ、Stringの親クラスはObjectで、Objectの親クラスはBasicObjectなんですね〜。複雑!実に複雑!
もちろんStringクラスを親クラスにして、新しいクラスを作成することもできます。
1 2 3 4 5 6 |
>> s = Word.new("level") # 新しいWordを作成し、"level" で初期化する => "level" >> s.palindrome? # Wordが回文かどうかを調べるメソッド => true >> s.length # WordはStringで扱える全てのメソッドを継承している => 5 |
上記の例では、Stringを親クラスにWordクラスを作成しています。Wordクラスでは新しく作ったメソッドだけでなく、Stringクラスのメソッドも全て使うことができます。
組み込みクラスの変更
これは驚きました。なんとRubyでは、誰でも基本クラスを拡張できちゃうみたいです。
なので例えば、さっきWordクラスに追加したメソッドはStringクラスにも追加することができちゃうのです。
1 2 3 4 5 6 7 8 9 |
>> class String >> # 文字列が回文であればtrueを返す >> def palindrome? >> self == self.reverse >> end >> end => :String >> "deified".palindrome? => true |
これはすごい!(迫真)
しかしこのような大いなる力には大いなる責任が伴うようです。使い方を間違えないように気をつけましょう…
コントローラークラス
さらばRuby!ただいまRails!
基本的なクラスの知識を身につけたので、ようやくRailsに戻ります。Railsのコントローラークラスを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
>> controller = StaticPagesController.new => #<StaticPagesController:0x22855d0> >> controller.class => StaticPagesController >> controller.class.superclass => ApplicationController >> controller.class.superclass.superclass => ActionController::Base >> controller.class.superclass.superclass.superclass => ActionController::Metal >> controller.class.superclass.superclass.superclass.superclass => AbstractController::Base >> controller.class.superclass.superclass.superclass.superclass.superclass => Object |
複雑ですが、下記のような構造になってるみたいです。
複雑スギィ!まあ何となくはわかりますけどね。AbstractControllerが全Controllerの元になってて、用途別に色んなControllerを派生させてる感じなんですかね。
ActionControllerとApplicationなど、結構深く分かれてるので、全コントローラーを図示すると樹形図みたくなりそうですね。
ユーザークラス
最後に完全なクラスを作ってみましょうという回でした。
まあこれはソースコードを見ればわかるのではないでしょうか。
1 2 3 4 5 6 7 8 9 10 11 12 |
class User attr_accessor :name, :email def initialize(attributes = {}) @name = attributes[:name] @email = attributes[:email] end def formatted_email "#{@name} <#{@email}>" end end |
まずはinitializeメソッド!これはもう形が決まっていて、attributesを引数にとるようになっています。
そしてインスタンス内で使う変数はインスタンス変数と呼ばれ、Rubyでは変数の先頭に@をつけるようになっています
formatted_emailは普通のメソッドです。名前とメアドを組み合わせた文字列を生成します。
まとめ
Rails Tutorial4章はほとんど文法の説明でしたね。正直あんまり記事にするところがなかったというか^^;
実際記事にしてみても、書いてある説明とコードを羅列しただけになっちゃいましたね。謎のエラーにハマってどう対応したかとかを書くのがこの記事の目的でもあるんですが…
まあまだ4章です。全14章あることを考えるとまだまだ闇はあるのでしょう…
次回、5章に続く!