Rails Tutorial Chapter5をやる 断片的、そして適当なメモ
Rails Tutorialも第5章です。メモを取りながらやっているのですが、いかんせん日にちが経っている(実は今10章まで進んだw)
なのでほとんどメモをコピペしてるだけですが・・・。
第4章はRailsというよりRubyの基本的な構文についてなので、初心者の方はやるとよろしいかと存じますが、まあサラッとチェックしただけに留めて次へ行きます。
この章で学ぶ(学んだ)こと(適当訳)
Chapter 5: Filling in the layout | Ruby on Rails Tutorial (3rd Ed.) | Softcover.io
- HTML5を使う。ロゴ、ヘッダー、フッター、メインのコンテントなどサイトのレイアウトを決めていく。
- パーシャルを使ってマークアップを複数のファイルに切り分けていく。便利。
- CSSのクラスやらidやらを使っていきます。
- Bootstrapも使う。手っ取り早くいい感じのデザインができます。
- SassとアセットパイプラインでCSSの重複を排除し、その結果を本番環境用に効率的にパッケージングすることができる。
- Railsはカスタムのルーティングの決まりがあって、それにより名前付きのルートを提供できる。
- 結合テストにより、ブラウザでクリックしてページ遷移、というのを効果的にシュミレートすることができる。
いったいどうゆうことなんでしょうね(半ギレ)
Bootstrapの導入
とうとうBootstrapを導入して、本格的にレイアウト作っていく、ということで。
まず、今までホーム、ヘルプ、ログインページを作ったはいいんですけど、個々へアクセスするためのリンクがないなと。
マスターからブランチを切ります。
$ git checkout -b filling-in-layout
レイアウトのカスタマイズ
各画面に共通するレイアウトを作っていきます。
app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> <!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]--> </head> <body> <header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app", '#', id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", '#' %></li> <li><%= link_to "Help", '#' %></li> <li><%= link_to "Log in", '#' %></li> </ul> </nav> </div> </header> <div class="container"> <%= yield %> </div> </body> </html>
<!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]-->
HTML5に対応してないless than IE9に対してはhtml5shiv
を使うようにするぜと。
コメントアウトしているのが奇妙だが、これでいいの・・・かな?
日本のブラウザバージョン別シェアグラフ2014 (StatCounter Global Statsより)
ここを見るとIE9以前もちらほらありますな。
ヘッダー
<header class="navbar navbar-fixed-top navbar-inverse">
navbar
などのクラスはBootstrapのクラスですけど、まだインストールしてないので、スタイル適用されない形で表示されるかと。
ナビ
<%= link_to "sample app", '#', id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", '#' %></li> <li><%= link_to "Help", '#' %></li> <li><%= link_to "Log in", '#' %></li> </ul> </nav>
link_toヘルパーを使っていくよと。ただしリンク先は仮で。
<nav> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Home</a></li> <li><a href="#">Help</a></li> <li><a href="#">Log in</a></li> </ul> </nav>
要はこういう意味合いになる。HTML5だと。
<div class="container"> <%= yield %> </div>
この部分に各画面の個別のレイアウトが表示されていきます。
ホーム画面のカスタマイズ
app/views/static_pages/home.html.erb
<div class="center jumbotron"> <h1>Welcome to the Sample App</h1> <h2> This is the home page for the <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a> sample application. </h2> <%= link_to "Sign up now!", '#', class: "btn btn-lg btn-primary" %> </div> <%= link_to image_tag("rails.png", alt: "Rails logo"), 'http://rubyonrails.org/' %>
jumbotron
は今まで使ったことなかったかも。でかい。
btn-lg
もBootstrapのクラス。大きめのボタンになる。
http://getbootstrap.com/components/#jumbotron
画面下部にlink_to
,image_tag
画像にリンクを張っているんですね。
<%= link_to image_tag("rails.png", alt: "Rails logo"), 'http://rubyonrails.org/' %>
image_tag使用しているのはいいけど、肝心の画像がないですよと。
Rails Tutorialのロゴを取ってくることができるようです。
アプリのルートディレクトリ上にて
$ curl -O http://rubyonrails.org/images/rails.png % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 13036 100 13036 0 0 22979 0 --:--:-- --:--:-- --:--:-- 38228 $ ls app bin config config.ru db Gemfile Gemfile.lock Guardfile layout_file lib log public rails.png Rakefile README.md test tmp vendor
こうしてルートにDLしてからの、app/assets/images/
に移動させる。
$ mv rails.png app/assets/images/
まだBootstrap導入してないのでこんな感じ。
5.1.2 Bootstrap and custom CSS
Gemfileの編集
Bootstrapを導入します。RailsのアセットパイプラインでサポートしているSassも使えるように、bootstrap-sass
を導入します。
source 'https://rubygems.org' gem 'rails', '4.2.0' gem 'bootstrap-sass', '3.2.0.0' . . .
$ bundle install
カスタムCSSの作成
app/assets/stylesheetsにcustom.css.scss
というファイルを作成します。
$ touch app/assets/stylesheets/custom.css.scss
そしてそこでBootstrapのインポート。
@import "bootstrap-sprockets"; @import "bootstrap";
rails s
すると、Bootstrapが適用されてる!
さらにカスタマイズしていきます。
@import "bootstrap-sprockets"; @import "bootstrap"; /* universal */ html { overflow-y: scroll; } body { padding-top: 60px; } section { overflow: auto; } textarea { resize: vertical; } .center { text-align: center; } .center h1 { margin-bottom: 10px; }
全体のセッティング。.center
クラスの内容は文字を真ん中寄せにする。ちゃんとクラスの名前と内容を一致させているんだなあと。
これからCSSを書くときも気をつけていきたい点ですね。
Typography
- letter-spacing
normal 標準の間隔にします。これが初期値です。 数値で指定 数値にpxやemやexなどの単位をつけて指定します。尚、pxとは1ピクセルを1とする単位で、実際に表示されるサイズは72dpiや96dpiといったモニタの解像度により変化します。また、emとはフォントの高さを1とする単位で、exとは小文字の「x」の高さを1とする単位です。
この場合-2px
とすることにより、文字の感覚がぎゅっと詰まった。
h1 { font-size: 3em; letter-spacing: -2px; margin-bottom: 30px; /* ? */ text-align: center; /* ? */ }
ここら辺はよくわからないなあ。先に.center
でtext-align: conter;
と、h1
にmargin-bottom: 10px
を指定しているので、ここでわざわざ指定し直す必要もないと思うんだけど。実際見た目も変わりない?なあ。
でもなんか様になってきたぞ〜。
ヘッダー部分のカスタマイズ
/* header */ #logo { float: left; margin-right: 10px; font-size: 1.7em; color: #fff; text-transform: uppercase; letter-spacing: -1px; padding-top: 9px; font-weight: bold; } #logo:hover { color: #fff; text-decoration: none; }
font-size: 1.7em
なので、h2より大きいですね。
text-transform: uppercase;
なんてのがあるんだ! タイトルが大文字になった!
んー、カコイイねー。
5.1.3 Partials
共通レイアウトに記述していたこの部分を
<!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]-->
パーシャルにして切り分けてしまおうと。
app/views/layouts/_shim.html.erb
を作って、そこにIE9以前に対応する部分を突っ込む。
<!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> <%= render 'layouts/shim' %> # ここ置換え </head> <body> <%= render 'layouts/header' %> <div class="container"> <%= yield %> </div> </body> </html>
<%= render 'layouts/shim' %>
でそのパーシャルを表示させる。_
はつけなくてよし。
_header.html.erb
というパーシャルを作ってそこに突っ込む。
app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app", '#', id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", '#' %></li> <li><%= link_to "Help", '#' %></li> <li><%= link_to "Log in", '#' %></li> </ul> </nav> </div> </header>
フッターも作ります。
app/views/layouts/_footer.html.erb
<footer class="footer"> <small> The <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a> by <a href="http://www.michaelhartl.com/">Michael Hartl</a> </small> <nav> <ul> <li><%= link_to "About", '#' %></li> <li><%= link_to "Contact", '#' %></li> <li><a href="http://news.railstutorial.org/">News</a></li> </ul> </nav> </footer>
それらを共通レイアウトの中で表示
app/views/layouts/application.html.erb
<body> <%= render 'layouts/header' %> <div class="container"> <%= yield %> <%= render 'layout/footer' %> </div> </body>
5.2.1 The asset pipeline
Nesting on Sass
.center { text-align: center; } .center h1 { margin-bottom: 10px; }
Sassだとこのようにnestできる
.center { text-align: center; h1 { margin-bottom: 10px; } }
#logo { float: left; margin-right: 10px; font-size: 1.7em; color: #fff; text-transform: uppercase; letter-spacing: -1px; padding-top: 9px; font-weight: bold; } #logo:hover { color: #fff; text-decoration: none; }
logo
というidに付加するhover
属性も、このようにネストできる。
#logo { float: left; margin-right: 10px; font-size: 1.7em; color: #fff; text-transform: uppercase; letter-spacing: -1px; padding-top: 9px; font-weight: bold; &:hover { color: #fff; text-decoration: none; } }
#logo:hover
=> &:hover
になると。
footer { margin-top: 45px; padding-top: 5px; border-top: 1px solid #eaeaea; color: #777 a { color: #555; &:hover { color: #222; } } small { float: left; } ul { float: right; list-style: none; li { float: left; margin-left: 15px; } } }
footerのスタイルもこのようにネストできるが・・・なんかわけかわらんくなっとるw
Variables
Lessだと@gray-light: #777;
というふうにするみたいだが、Sassだと$gray-light: #777;
BootstrapはLessだが、今の場合gem bootstrap-sass
をインストールしてるので、Sassでよい。
http://getbootstrap.com/customize/#less-variables
5.3 Layout links
get 'static_pages/help' get 'static_pages/about' get 'static_pages/contact'
このままだと/static_pages/なんたら
というurlになっちゃうので。
config/routes.db
get 'help' => 'static_pages#help' get 'about' => 'static_pages#about' get 'contact' => 'static_pages#contact'
help_path -> '/help'
help_url -> 'http://www.example.com/help'
5.3.4 Layout link tests
Home画面のリンクが正しく表示されるかどうかを、いちいちポチポチ押して確認するのめんどいよねと。
Integration test
$ rails generate integration_test site_layout
複数のアクションやコントローラにまたがる挙動を検証するためのテスト
Note that the Rails generator automatically appends _test to the name of the test file.
https://www.railstutorial.org/book/filling_in_the_layout
テストファイルは_test
が追記された形で生成される。
$ rails g integration_test site_layout
invoke test_unit
create test/integration/site_layout_test.rb
require 'test_helper' class SiteLayoutTest < ActionDispatch::IntegrationTest test "layout links" do get root_path assert_template 'static_pages/home' assert_select "a[href=?]", root_path, count: 2 assert_select "a[href=?]", help_path assert_select "a[href=?]", about_path assert_select "a[href=?]", contact_path end end
- ルートにアクセス
static_pages/home
というテンプレートが表示されているか。assert_select
でセレクタを確認。- ルートへのリンクが2つあるか。
- ヘルプ、アバウト、コンタクトへのそれぞれのリンクがあるか。
5.4 User signup: A first step
$ rails g controller Users new
config/routes.rb
get 'signup' => 'users#new'
integration testにおいて、signup_path
にアクセスした時に、ページタイトルが'Sign up'になってるかどうかテストしたい。
まず、page titleを設定しているのはApplicationHelper
に定義したfull_title
ヘルパーでした。その戻り値が正しいかどうかを確認すればいいわけです。
だからまず、test_helper.rb
にApplicationHelper
をインクルードしないといけません。
test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test' . . . class ActiveSupport::TestCase fixtures :all include ApplicationHelper . . . end
integration testでfull_title
ヘルパーを使います。
require 'test_helper' class SiteLayoutTest < ActionDispatch::IntegrationTest test "layout links" do get root_path . . . # ここから get signup_path # signup pageにアクセスしたときに・・・ assert_select "title", full_title("Sign up") # <title>タグ内のテキストが"Sign up"になってるかどうか end end
あれ? メモがここで終わってるなあ。このあとはサインアップ用のリンクを設定するなどの話なんですけど・・・だから早くブログに書けとあれほど(ry
5.4.2 Signup URL
https://www.railstutorial.org/book/filling_in_the_layout#sec-signup_url
config/routes.rb
Rails.application.routes.draw do root 'static_pages#home' get 'help' => 'static_pages#help' get 'about' => 'static_pages#about' get 'contact' => 'static_pages#contact' get 'signup' => 'users#new' # ここ end
users#new
アクションに紐付いたsignup
というルートを設定。
app/views/static_pages/home.html.erb
<div class="center jumbotron"> <h1>Welcome to the Sample App</h1> <h2> This is the home page for the <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a> sample application. </h2> <%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %> # ここ </div> <%= link_to image_tag("rails.png", alt: "Rails logo"), 'http://rubyonrails.org/' %>
今までリンクに仮の#
を設定していた部分にsignup_path
を設定。
対応するビューであるapp/views/users/new.html.erb
にこう記述。
<% provide(:title, 'Sign up') %> <h1>Sign up</h1> <p>This will be a signup page for new users.</p>
ページのタイトルはprovide
を使用する。
こんな感じで仮のnewページ。
ページタイトルもSign up
+ ベースタイトルとなっている。
今章はまだRailsというよりはCSS(Sass)とかBootstrapとかの話かと。
軽くレイアウトと決めつつ進めていく感じ。しかしながらテストもでてきましたので、そこら辺もっと勉強していきたいなと。
その他
- line-height
normal ブラウザが判断して行の高さを決定します。これが初期値です。
数値に単位をつけて指定
数値にpxやemやexなどの単位をつけて指定します。pxとは1ピクセルを1とする単位で、実際に表示されるサイズは72dpiや96dpiといったモニタの解像度により変化します。また、emとはフォントの高さを1とする単位で、exとは小文字の「x」の高さを1とする単位です。
数値のみで指定
単位をつけずに数値のみを指定すると、その数値にフォントのサイズを掛けた値が行の高さとなります。例えば「1.5」と指定すると「150%」や「1.5em」と指定した場合と同じになります。
%で指定
%値で指定します
恥ずかしながらまだまだCSSがよくわかってないなあ。
- font-size
http://www.htmq.com/style/font-size.shtml
数値で指定
数値にpxやemやexなどの単位をつけて指定します。pxとは1ピクセルを1とする単位で、実際に表示されるサイズは72dpiや96dpiといったモニタの解像度により変化します。また、emとはフォントの高さを1とする単位で、exとは小文字の「x」の高さを1とする単位です。数値には負の値は指定できません。
%で指定
%値で指定します。
キーワードで指定
xx-small、x-small、small、medium、large、x-large、xx-largeの7段階があり、mediumが標準サイズです。1段階上がると1.2倍のサイズになります。また、smaller、largerを指定すると大きさが1段階上下します。
アセットを入れるところが何個かあるんだな。
In the latest version of Rails, there are three canonical directories for static assets, each with its own purpose:
app/assets: assets specific to the present application lib/assets: assets for libraries written by your dev team vendor/assets: assets from third-party vendors
(日本語版)
http://railstutorial.jp/chapters/filling-in-the-layout?version=4.0#sec-the_asset_pipeline
Rails 3.1以降では、静的ファイルを目的別に分類する、標準的な3つのディレクトリが使用されるようになりました。Rails 4.0でも同様です。
app/assets: 現在のアプリケーション固有のアセット lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット vendor/assets: サードパーティのアセット