個人的リマインド用
参考
Ruby on Rails チュートリアル プロダクト開発の0→1を学ぼう
Rails風味のRuby
組み込みヘルパー
application.htmlから抜粋
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
ここではRailsの組み込み関数stylesheet_link_tagを使って、application.cssをすべてのメディアタイプで使えるようにしている。この行には戸惑うRubyの概念が4つある。Railsの組み込み関数、括弧を使わないメソッド呼び出し、シンボル、そしてハッシュ。
カスタムヘルパー
新しく作ったメソッドのことをカスタムヘルパーという。
例:full_titleというカスタムヘルパーを作って、titleのコードを書き換える。
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
このヘルパーを使うと
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
から
<title><%= full_title(yield(:title)) %></title>
になる。置き換えた結果
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title> ←追加
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="utf-8">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
</head>
<body>
<%= yield %>
</body>
</html>
test/controllers/static_pages_controller_test.rb
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
app/views/static_pages/home.html.erb
(テストをパスするためにprovideを消す)
<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>
文字列とメソッド
初歩的なところは飛ばしていく
式展開
first_name = "Michael"
"#{first_name} Hartl" ←文字列内に変数を展開
オブジェクトとメッセージ受け渡し
Rubyではあらゆるものがオブジェクト。文字列やnilですらオブジェクト。
"foobar".length 文字列にlengthというメソッドを呼ぶと文字数が返ってくる
=> 6
"foobar".empty? 特定のメソッドの最後に?をつけると倫理値が帰ってくる
=> false
nil.to_s.empty?
メソッドチェーンで繋げることもできる
puts "x is not empty" if !x.empty?
puts "x is not empty" unless x.empty?
!やunlessで否定形
!!nil
=> false
!!を先頭につけると強制的に論理値を返すように。falseとnilがfalse。他は全部true
メソッドの定義
デフォルト値: 引数に何も渡されない時に使う値
def string_message(str = '')
Rubyのメソッドには暗黙の戻り値がある。メソッドの最後に評価した値を自動的に返すというもの。returnを使えば明示的に返すことができる。
以上の知識で最初のコードを評価できる
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
最後にmoduleに関しては、互いに関連する複数のメソッドをまとめる方法の1つで、includeメソッドを使ってモジュールを読み込むことができる。これをミックスインと呼ぶ。ちなみにRubyのコードを書くのならば、モジュールを作成するたびに明示的に読み込んで使うのが普通だが、Railsでは自動的にヘルパーモジュールを読み込んでくれるので、includeを書かなくていい。つまりfull_titleメソッドは自動的に全てのビューで利用できるようになっている。
配列に関して
split
"foo bar baz".split #文字列を3つの要素を持つ配列に分割する
=> ["foo", "bar", "baz"]
"fooxbarxbaz".split('x') #空白ではなく指定の文字でも分割できる
代入
>> a = [42, 8, 17]
>> a.push(6) # 6を配列に追加する
=> [42, 8, 17, 6]
>> a << 7 # 7を配列に追加する
=> [42, 8, 17, 6, 7]
>> a << "foo" << "bar" # 配列に連続して追加する
=> [42, 8, 17, 6, 7, "foo", "bar"]
join
>> a
=> [42, 8, 17, 6, 7, "foo", "bar"]
>> a.join # 単純に連結する
=> "4281767foobar"
>> a.join(', ') # カンマ+スペースを使って連結する
=> "42, 8, 17, 6, 7, foo, bar"
range
>> 0..9
=> 0..9
>> (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
配列の取り出し
>> a = %w[foo bar baz quux] # %wを使って文字列の配列に変換
=> ["foo", "bar", "baz", "quux"]
>> a[0..2]
=> ["foo", "bar", "baz"]
ブロック
こういうの
>> (1..5).each { |i| puts 2 * i }
2
4
6
8
10
=> 1..5
{ |i| puts 2 * i }の部分がブロックと呼ばれている。
{}ではなくdo,endにすることもできる。その場合は1行では書けない。
>> (1..5).each do |i|
?> puts 2 * i
>> end
2
4
6
8
10
=> 1..5
timesやmapを使った場合
>> 3.times { puts "Betelgeuse!" } # 3.timesではブロックに変数を使っていない
"Betelgeuse!"
"Betelgeuse!"
"Betelgeuse!"
=> 3
>> (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"]
{ |char| char.メソッド名 }の部分を、&:メソッド名にすることもできる
>> %w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]
>> %w[A B C].map(&:downcase)
=> ["a", "b", "c"]
ハッシュとシンボル
ハッシュ
キーと値を保存するもの
user["first_name"] = "Michael"
user["first_name"]
=> "Michael"
こういう書き方もあれば
user = { "first_name" => "Michael", "last_name" => "Hartl" }
こういう書き方もある。
しかしRailsでは文字列よりもシンボルを使う方が一般的。
>> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name]
=> "Michael Hartl"
>> user[:password]
=> nil
そしてその後にJavaScriptみたいに書けるようになった
>> h2 = { name: "Michael Hartl", email: "michael@example.com" }
さらにハッシュの中にハッシュを入れられる(ネストされたハッシュ)
>> params = {}
=> {}
>> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" }
=> {:name=>"Michael Hartl", :email=>"mhartl@example.com"}
>> params
=> {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}}
>> params[:user][:email]
=> "mhartl@example.com"
CSSについて
上記の内容でcssの読み込み文が理解できるはず
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
疑問点
1.丸括弧がない
→Rubyではメソッド呼び出しの丸括弧は無視していい
# メソッド呼び出しの丸カッコは省略可能。
stylesheet_link_tag("application", "data-turbo-track": "reload")
# 上は以下のように書いても同じ
stylesheet_link_tag "application", "data-turbo-track": "reload"
2.ハッシュの波括弧がない
→ハッシュがメソッド呼び出しの最後の引数である場合は、波括弧を省略できる。
# 最後の引数がハッシュの場合、波カッコは省略可能。
stylesheet_link_tag("application", { "data-turbo-track": "reload" })
# 上は以下のように書いても同じ
stylesheet_link_tag("application", "data-turbo-track": "reload")
ちなみに最初の引数は、スタイルシートへのパスを指定する文字列。次の引数はTurbo(のちに説明)の設定を1個含んでいる。
コンストラクタ
文字列のインスタンスを作成
s = "foobar"
s.class
=> String
これは文字列のオブジェクトを暗黙で作成するリテラルコンストラクタ
s = String.new("foobar")
s.class
=> String
s == "foobar"
=> true
これは明示的な名前付きコンストラクタ
配列でも、文字列と同様にインスタンスを生成できる。
a = Array.new([1, 3, 2])
=> [1, 3, 2]
ただしハッシュは少し異なり、配列のコンストラクタであるArray.newは配列の初期値を引数に取るが、Hash.newはハッシュのデフォルト値を引数に取る。
h = Hash.new
=> {}
h[:foo] #存在しない値にアクセス
=> nil
h = Hash.new(0) #存在しないキーのデフォルト値をnilから0にする
h[:foo]
=> 0
メソッドがクラス自身(この場合はnew)に対して呼び出される時、このメソッドをクラスメソッドと呼ぶ。クラスのnewメソッドを呼び出した結果は、そのクラスのオブジェクトであり、これはクラスのインスタンスとも呼ばれる。lenggthのように、インスタンスに対して呼び出すメソッドはインスタンスメソッドと呼ばれる。
クラスの継承
最初の方は飛ばす。
>> class Word < String # WordクラスはStringクラスを継承する
>> # 文字列が回文であればtrueを返す
>> def palindrome?
>> self == self.reverse # selfは文字列自身を表します
>> end
>> end
Rubyではselfを使うと自分自身を指定できる。Wordクラスの中では、selfはオブジェクト自身を指す。
self == self.reverse
Stringクラスの内部では、メソッドや属性を呼び出すときのself.も省略可能
self == reverse
アクセサー
class User
attr_accessor :name, :email #←アクセサー
def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end
def formatted_email
"#{@name} <#{@email}>"
end
end
アクセサーを作成すると、そのデータを取り出すメソッド(getter)と、データに代入するメソッド(setter)をそれぞれ定義してくれる。具体的には、この行を実行したことにより、インスタンス変数@nameと@emailにアクセスするためのメソッドが用意される。
initializeは特殊なメソッドで、User.newを実行すると自動的に呼び出される。initializeメソッドはattributesという引数を1つとる。
def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end
上のコードでattributes変数はからのハッシュをデフォ値としてもつため、名前やメールアドレスのないユーザーを作れる。存在しないキーに対してハッシュはnilを返すので、:nameキーがなければattributes[:name]はnilになる。