Rails Tutorial 4 Rails-flavored Ruby
Rails Tutorial 4 Rails-flavored Ruby
ここまで Rails を諸々触ってきたが、この章では Rails 習得に必須となる Ruby の様々な要素に触れていく。
高度なセットアップ
前章で見落としていた項目があったので追加。
minitestレポーター
minitest の実行結果を RED/GREEN で表示できるようにする。
minitest-reporters gem を使用する。
ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' require "minitest/reporters" Minitest::Reporters.use! class ActiveSupport::TestCase # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all # Add more helper methods to be used by all tests here... end
これで成功時は GREEN, 失敗時は RED で出力されるようになる。
Guardによるテストの自動化
統合テストとビューが更新されたら自動的に適切なテストが実行できるようにする。
$ bundle exec guard init
上記コマンドを実行すると /home/ubuntu/workspace/sample_app/Guardfile
が生成される。
下記のように書き換えることで、ファイル書き換えの度に適切なテストのみが実行されるようになる。
# Defines the matching rules for Guard. guard :minitest, spring: true, all_on_start: false do watch(%r{^test/(.*)/?(.*)_test\.rb$}) watch('test/test_helper.rb') { 'test' } watch('config/routes.rb') { integration_tests } watch(%r{^app/models/(.*?)\.rb$}) do |matches| "test/models/#{matches[1]}_test.rb" end watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches| resource_tests(matches[1]) end watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches| ["test/controllers/#{matches[1]}_controller_test.rb"] + integration_tests(matches[1]) end watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches| integration_tests(matches[1]) end watch('app/views/layouts/application.html.erb') do 'test/integration/site_layout_test.rb' end watch('app/helpers/sessions_helper.rb') do integration_tests << 'test/helpers/sessions_helper_test.rb' end watch('app/controllers/sessions_controller.rb') do ['test/controllers/sessions_controller_test.rb', 'test/integration/users_login_test.rb'] end watch('app/controllers/account_activations_controller.rb') do 'test/integration/users_signup_test.rb' end watch(%r{app/views/users/*}) do resource_tests('users') + ['test/integration/microposts_interface_test.rb'] end end # Returns the integration tests corresponding to the given resource. def integration_tests(resource = :all) if resource == :all Dir["test/integration/*"] else Dir["test/integration/#{resource}_*.rb"] end end # Returns the controller tests corresponding to the given resource. def controller_test(resource) "test/controllers/#{resource}_controller_test.rb" end # Returns all tests for the given resource. def resource_tests(resource) integration_tests(resource) << controller_test(resource) end
と思いきや、
Note: As of this writing, there is an interaction bug between Guard and Spring that causes all the tests to run every time. I’m keeping an eye on the issue and will update this section when it’s resolved.
とのことで全部のテストが実行されてしまう。
.gitignore に以下を追記する。
# Ignore Spring files. /spring/*.pid
新しいターミナルで以下を実行しておく。
$ bundle exec guard
これでファイル更新時にテストが実行される。
また、guard>
プロンプトが出ている状態でエンターキーを押せば全テストが実行されることが確認できる。
git にコミットしておく。
$ git add -A $ git commit -m "Complete advanced setup"
Rails風味のRuby
カスタムヘルパーの作成
各ページのタイトルについて、
- ページタイトルが provide で与えられていたらそれを使用して表示
- なければデフォルトのタイトルを表示
という挙動を実現する。
app/helpers/application_helper.rb
module ApplicationHelper # Returns the full title on a per-page basis. 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
上記を使用するように app/views/layouts/application.html.erb
を書き換える。
<!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <%= yield %> </body> </html>
これで、Homeページにこれまで表示されていた余分な「Home」という単語を表示せず、基本タイトルのみを正しく表示できるようになる。
その修正を加える前にテストを変更する。
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 を消すだけ。
これでテストが通って修正完了。
Ruby の学習
ここからはRailsコンソールを使用してRubyを学んでいく。
以下が筆者の好きな設定だそうな。
~/.irbrc
IRB.conf[:PROMPT_MODE] = :SIMPLE IRB.conf[:AUTO_INDENT_MODE] = false
ここから特にハマるところはなくチュートリアル通りに進めていくのみ。
この章で学んだこと。
- Rubyは文字列を扱うためのメソッドを多数持っている
- Rubyの世界では、すべてがオブジェクトである
- Rubyではdefというキーワードを使ってメソッドを定義する
- Rubyではclassというキーワードを使ってクラスを定義する
- Railsのビューでは静的なHTMLと埋め込みRuby(ERb)が使える
- Rubyの組み込みクラスには配列、範囲、ハッシュなどがある
- Rubyのブロックは (他の似た機能と比べ) 柔軟な機能で、添え字を使ったデータ構造よりも自然にイテレーションができる
- シンボルとはラベルである。追加的な構造を持たない (代入などができない) 文字列みたいなもの。
- Rubyではオブジェクトを継承できる
- Rubyでは組み込みクラスですら内部を見たり修正したりできる
- 「“deified”」という単語は回文である
最後の1行はこちらから。
(Rubyで組み込みクラスにメソッドを追加できるということは実にクールですが、"deified" (=神格化された) という単語が回文になっていることも、それに劣らずクールではないでしょうか。)