3章を始める。これから作るサンプルは、長くいじることになるらしい。
3.1
> bundle exec rails _5.1.6_ new sample_app --skip-bundle create create README.md create Rakefile create config.ru create .gitignore create Gemfile run git init from "." Initialized empty Git repository in /Users/tambara/study/rails_study/sample_app/.git/ create app create app/assets/config/manifest.js create app/assets/javascripts/application.js create app/assets/javascripts/cable.js create app/assets/stylesheets/application.css create app/channels/application_cable/channel.rb create app/channels/application_cable/connection.rb create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/jobs/application_job.rb create app/mailers/application_mailer.rb create app/models/application_record.rb create app/views/layouts/application.html.erb create app/views/layouts/mailer.html.erb create app/views/layouts/mailer.text.erb create app/assets/images/.keep create app/assets/javascripts/channels create app/assets/javascripts/channels/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep create bin create bin/bundle create bin/rails create bin/rake create bin/setup create bin/update create bin/yarn create config create config/routes.rb create config/application.rb create config/environment.rb create config/secrets.yml create config/cable.yml create config/puma.rb create config/spring.rb create config/environments create config/environments/development.rb create config/environments/production.rb create config/environments/test.rb create config/initializers create config/initializers/application_controller_renderer.rb create config/initializers/assets.rb create config/initializers/backtrace_silencers.rb create config/initializers/cookies_serializer.rb create config/initializers/cors.rb create config/initializers/filter_parameter_logging.rb create config/initializers/inflections.rb create config/initializers/mime_types.rb create config/initializers/new_framework_defaults_5_1.rb create config/initializers/wrap_parameters.rb create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create lib create lib/tasks create lib/tasks/.keep create lib/assets create lib/assets/.keep create log create log/.keep create public create public/404.html create public/422.html create public/500.html create public/apple-touch-icon-precomposed.png create public/apple-touch-icon.png create public/favicon.ico create public/robots.txt create test/fixtures create test/fixtures/.keep create test/fixtures/files create test/fixtures/files/.keep create test/controllers create test/controllers/.keep create test/mailers create test/mailers/.keep create test/models create test/models/.keep create test/helpers create test/helpers/.keep create test/integration create test/integration/.keep create test/test_helper.rb create test/system create test/system/.keep create test/application_system_test_case.rb create tmp create tmp/.keep create tmp/cache create tmp/cache/assets create vendor create vendor/.keep create package.json remove config/initializers/cors.rb remove config/initializers/new_framework_defaults_5_1.rb > cd sample_app/ > vi Gemfile > bundle install --without production Fetching gem metadata from https://rubygems.org/......... Fetching gem metadata from https://rubygems.org/. Resolving dependencies.... Using rake 12.3.1 Using concurrent-ruby 1.1.3 Using i18n 1.1.1 Using minitest 5.10.3 Using thread_safe 0.3.6 Using tzinfo 1.2.5 Using activesupport 5.1.6 Using builder 3.2.3 Using erubi 1.7.1 Using mini_portile2 2.3.0 Using nokogiri 1.8.5 Using rails-dom-testing 2.0.3 Using crass 1.0.4 Using loofah 2.2.3 Using rails-html-sanitizer 1.0.4 Using actionview 5.1.6 Using rack 2.0.6 Using rack-test 1.1.0 Using actionpack 5.1.6 Using nio4r 2.3.1 Using websocket-extensions 0.1.3 Using websocket-driver 0.6.5 Using actioncable 5.1.6 Using globalid 0.4.1 Using activejob 5.1.6 Using mini_mime 1.0.1 Using mail 2.7.1 Using actionmailer 5.1.6 Using activemodel 5.1.6 Using arel 8.0.0 Using activerecord 5.1.6 Fetching ansi 1.5.0 Installing ansi 1.5.0 Using bindex 0.5.0 Using bundler 1.17.1 Using byebug 9.0.6 Fetching coderay 1.1.2 Installing coderay 1.1.2 Using coffee-script-source 1.12.2 Using execjs 2.7.0 Using coffee-script 2.4.1 Using method_source 0.9.2 Using thor 0.20.3 Using railties 5.1.6 Using coffee-rails 4.2.2 Using ffi 1.9.25 Fetching formatador 0.2.5 Installing formatador 0.2.5 Using rb-fsevent 0.10.3 Using rb-inotify 0.9.10 Using ruby_dep 1.5.0 Using listen 3.1.5 Fetching lumberjack 1.0.13 Installing lumberjack 1.0.13 Fetching nenv 0.3.0 Installing nenv 0.3.0 Fetching shellany 0.0.1 Installing shellany 0.0.1 Fetching notiffany 0.1.1 Installing notiffany 0.1.1 Fetching pry 0.12.2 Installing pry 0.12.2 Fetching guard 2.13.0 Installing guard 2.13.0 Fetching guard-compat 1.2.1 Installing guard-compat 1.2.1 Fetching guard-minitest 2.4.4 Installing guard-minitest 2.4.4 Using multi_json 1.13.1 Using jbuilder 2.7.0 Using jquery-rails 4.3.1 Fetching ruby-progressbar 1.10.0 Installing ruby-progressbar 1.10.0 Fetching minitest-reporters 1.1.14 Installing minitest-reporters 1.1.14 Using puma 3.9.1 Using sprockets 3.7.2 Using sprockets-rails 3.2.1 Using rails 5.1.6 Fetching rails-controller-testing 1.0.2 Installing rails-controller-testing 1.0.2 Using sass-listen 4.0.0 Using sass 3.7.2 Using tilt 2.0.8 Using sass-rails 5.0.6 Using spring 2.0.2 Using spring-watcher-listen 2.0.1 Using sqlite3 1.3.13 Using turbolinks-source 5.2.0 Using turbolinks 5.0.1 Using uglifier 3.2.0 Using web-console 3.5.1 Bundle complete! 20 Gemfile dependencies, 78 gems now installed. Gems in the group production were not installed. Use `bundle info [gemname]` to see where a bundled gem is installed. > git add --all > git commit -m "Initialize repository" (略)
外部のリポジトリにpushするのは面倒なので今回も止める。世の中に死ぬほどあるだろうし。
> vi app/controllers/application_controller.rb > vi config/routes.rb > git commit -am "Add hello" [master 9fcb567] Add hello 2 files changed, 5 insertions(+), 1 deletion(-) > heroku create Creating app... done, ⬢ salty-eyrie-75181 https://salty-eyrie-75181.herokuapp.com/ | https://git.heroku.com/salty-eyrie-75181.git > git push heroku master Counting objects: 90, done. Delta compression using up to 4 threads. Compressing objects: 100% (76/76), done. Writing objects: 100% (90/90), 20.32 KiB | 1.20 MiB/s, done. Total 90 (delta 6), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: ! Warning: Multiple default buildpacks reported the ability to handle this app. The first buildpack in the list below will be used. remote: Detected buildpacks: Ruby,Node.js remote: See https://devcenter.heroku.com/articles/buildpacks#buildpack-detect-order remote: -----> Ruby app detected remote: -----> Compiling Ruby/Rails remote: -----> Using Ruby version: ruby-2.4.5 remote: -----> Installing dependencies using bundler 1.15.2 remote: Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment remote: Warning: the running version of Bundler (1.15.2) is older than the version that created the lockfile (1.17.1). We suggest you upgrade to the latest version of Bundler by running `gem install bundler`. remote: Fetching gem metadata from https://rubygems.org/......... remote: Fetching version metadata from https://rubygems.org/.. remote: Fetching dependency metadata from https://rubygems.org/. remote: Fetching rake 12.3.1 remote: Fetching concurrent-ruby 1.1.3 remote: Fetching minitest 5.10.3 remote: Installing minitest 5.10.3 remote: Installing rake 12.3.1 remote: Installing concurrent-ruby 1.1.3 remote: Fetching thread_safe 0.3.6 remote: Installing thread_safe 0.3.6 remote: Fetching builder 3.2.3 remote: Installing builder 3.2.3 remote: Fetching erubi 1.7.1 remote: Installing erubi 1.7.1 remote: Fetching mini_portile2 2.3.0 remote: Fetching crass 1.0.4 remote: Installing mini_portile2 2.3.0 remote: Installing crass 1.0.4 remote: Fetching rack 2.0.6 remote: Fetching nio4r 2.3.1 remote: Fetching websocket-extensions 0.1.3 remote: Installing rack 2.0.6 remote: Installing websocket-extensions 0.1.3 remote: Fetching mini_mime 1.0.1 remote: Installing nio4r 2.3.1 with native extensions remote: Installing mini_mime 1.0.1 remote: Fetching arel 8.0.0 remote: Installing arel 8.0.0 remote: Using bundler 1.15.2 remote: Fetching coffee-script-source 1.12.2 remote: Installing coffee-script-source 1.12.2 remote: Fetching execjs 2.7.0 remote: Fetching method_source 0.9.2 remote: Installing execjs 2.7.0 remote: Installing method_source 0.9.2 remote: Fetching thor 0.20.3 remote: Fetching ffi 1.9.25 remote: Installing thor 0.20.3 remote: Fetching multi_json 1.13.1 remote: Installing multi_json 1.13.1 remote: Installing ffi 1.9.25 with native extensions remote: Fetching pg 0.20.0 remote: Installing pg 0.20.0 with native extensions remote: Fetching puma 3.9.1 remote: Installing puma 3.9.1 with native extensions remote: Fetching rb-fsevent 0.10.3 remote: Installing rb-fsevent 0.10.3 remote: Fetching tilt 2.0.8 remote: Installing tilt 2.0.8 remote: Fetching turbolinks-source 5.2.0 remote: Installing turbolinks-source 5.2.0 remote: Fetching tzinfo 1.2.5 remote: Installing tzinfo 1.2.5 remote: Fetching nokogiri 1.8.5 remote: Installing nokogiri 1.8.5 with native extensions remote: Fetching i18n 1.1.1 remote: Installing i18n 1.1.1 remote: Fetching websocket-driver 0.6.5 remote: Installing websocket-driver 0.6.5 with native extensions remote: Fetching mail 2.7.1 remote: Installing mail 2.7.1 remote: Fetching rack-test 1.1.0 remote: Installing rack-test 1.1.0 remote: Fetching sprockets 3.7.2 remote: Installing sprockets 3.7.2 remote: Fetching coffee-script 2.4.1 remote: Installing coffee-script 2.4.1 remote: Fetching uglifier 3.2.0 remote: Installing uglifier 3.2.0 remote: Fetching turbolinks 5.0.1 remote: Installing turbolinks 5.0.1 remote: Fetching rb-inotify 0.9.10 remote: Installing rb-inotify 0.9.10 remote: Fetching activesupport 5.1.6 remote: Installing activesupport 5.1.6 remote: Fetching sass-listen 4.0.0 remote: Installing sass-listen 4.0.0 remote: Fetching globalid 0.4.1 remote: Installing globalid 0.4.1 remote: Fetching activemodel 5.1.6 remote: Installing activemodel 5.1.6 remote: Fetching jbuilder 2.7.0 remote: Installing jbuilder 2.7.0 remote: Fetching sass 3.7.2 remote: Installing sass 3.7.2 remote: Fetching activejob 5.1.6 remote: Installing activejob 5.1.6 remote: Fetching activerecord 5.1.6 remote: Installing activerecord 5.1.6 remote: Fetching rails-dom-testing 2.0.3 remote: Fetching loofah 2.2.3 remote: Installing rails-dom-testing 2.0.3 remote: Installing loofah 2.2.3 remote: Fetching rails-html-sanitizer 1.0.4 remote: Installing rails-html-sanitizer 1.0.4 remote: Fetching actionview 5.1.6 remote: Installing actionview 5.1.6 remote: Fetching actionpack 5.1.6 remote: Installing actionpack 5.1.6 remote: Fetching actioncable 5.1.6 remote: Fetching actionmailer 5.1.6 remote: Fetching railties 5.1.6 remote: Installing actioncable 5.1.6 remote: Installing actionmailer 5.1.6 remote: Installing railties 5.1.6 remote: Fetching sprockets-rails 3.2.1 remote: Installing sprockets-rails 3.2.1 remote: Fetching jquery-rails 4.3.1 remote: Fetching coffee-rails 4.2.2 remote: Fetching rails 5.1.6 remote: Installing rails 5.1.6 remote: Installing coffee-rails 4.2.2 remote: Fetching sass-rails 5.0.6 remote: Installing sass-rails 5.0.6 remote: Installing jquery-rails 4.3.1 remote: Bundle complete! 20 Gemfile dependencies, 57 gems now installed. remote: Gems in the groups development and test were not installed. remote: Bundled gems are installed into ./vendor/bundle. remote: Post-install message from sass: remote: remote: Ruby Sass is deprecated and will be unmaintained as of 26 March 2019. remote: remote: * If you use Sass as a command-line tool, we recommend using Dart Sass, the new remote: primary implementation: https://sass-lang.com/install remote: remote: * If you use Sass as a plug-in for a Ruby web framework, we recommend using the remote: sassc gem: https://github.com/sass/sassc-ruby#readme remote: remote: * For more details, please refer to the Sass blog: remote: http://sass.logdown.com/posts/7081811 remote: remote: Bundle completed (43.05s) remote: Cleaning up the bundler cache. remote: -----> Installing node-v8.10.0-linux-x64 remote: -----> Detecting rake tasks remote: -----> Preparing app for Rails asset pipeline remote: Running: rake assets:precompile remote: Yarn executable was not detected in the system. remote: Download Yarn at https://yarnpkg.com/en/docs/install remote: I, [2018-11-22T02:24:18.141798 #1380] INFO -- : Writing /tmp/build_3949dec4a1dcf549174b4a04a8a8dadb/public/assets/application-7e084e44b9a13db0cda25bad2ac6fdbbfe31462ec93176e245cd0bcbc079f436.js remote: I, [2018-11-22T02:24:18.142211 #1380] INFO -- : Writing /tmp/build_3949dec4a1dcf549174b4a04a8a8dadb/public/assets/application-7e084e44b9a13db0cda25bad2ac6fdbbfe31462ec93176e245cd0bcbc079f436.js.gz remote: I, [2018-11-22T02:24:18.148641 #1380] INFO -- : Writing /tmp/build_3949dec4a1dcf549174b4a04a8a8dadb/public/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css remote: I, [2018-11-22T02:24:18.148797 #1380] INFO -- : Writing /tmp/build_3949dec4a1dcf549174b4a04a8a8dadb/public/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css.gz remote: Asset precompilation completed (2.60s) remote: Cleaning assets remote: Running: rake assets:clean remote: -----> Detecting rails configuration remote: remote: ###### WARNING: remote: remote: You have not declared a Ruby version in your Gemfile. remote: To set your Ruby version add this line to your Gemfile: remote: ruby '2.4.5' remote: # See https://devcenter.heroku.com/articles/ruby-versions for more information. remote: remote: ###### WARNING: remote: remote: Detecting rails configuration failed remote: set HEROKU_DEBUG_RAILS_RUNNER=1 to debug remote: remote: ###### WARNING: remote: remote: No Procfile detected, using the default web server. remote: We recommend explicitly declaring how to boot your server process via a Procfile. remote: https://devcenter.heroku.com/articles/ruby-default-web-server remote: remote: remote: -----> Discovering process types remote: Procfile declares types -> (none) remote: Default types for buildpack -> console, rake, web remote: remote: -----> Compressing... remote: Done: 41M remote: -----> Launching... remote: Released v6 remote: https://salty-eyrie-75181.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/salty-eyrie-75181.git * [new branch] master -> master
ここまではいままでと同じ。
3.2
まず、ブランチを切る。うん、正しいな。
> git checkout -b static-pages Switched to a new branch 'static-pages' > git branch master * static-pages
コントローラーをgenerateする
> bundle exec rails generate controller StaticPages home help create app/controllers/static_pages_controller.rb route get 'static_pages/help' route get 'static_pages/home' invoke erb create app/views/static_pages create app/views/static_pages/home.html.erb create app/views/static_pages/help.html.erb invoke test_unit create test/controllers/static_pages_controller_test.rb invoke helper create app/helpers/static_pages_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/static_pages.coffee invoke scss create app/assets/stylesheets/static_pages.scss
これでテンプレは作られる
3.2.1の演習をやってみよう。Fooというコントローラーを作って、消す。
> bundle exec rails g controller Foo bar baz create app/controllers/foo_controller.rb route get 'foo/baz' route get 'foo/bar' invoke erb create app/views/foo create app/views/foo/bar.html.erb create app/views/foo/baz.html.erb invoke test_unit create test/controllers/foo_controller_test.rb invoke helper create app/helpers/foo_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/foo.coffee invoke scss create app/assets/stylesheets/foo.scss > bundle exec rails destroy controller Foo bar baz remove app/controllers/foo_controller.rb route get 'foo/baz' route get 'foo/bar' invoke erb remove app/views/foo remove app/views/foo/bar.html.erb remove app/views/foo/baz.html.erb invoke test_unit remove test/controllers/foo_controller_test.rb invoke helper remove app/helpers/foo_helper.rb invoke test_unit invoke assets invoke coffee remove app/assets/javascripts/foo.coffee invoke scss remove app/assets/stylesheets/foo.scss
ふむ。
表示されるページの内容は、app/views/static_pages/home.html.erbなどを変更すれば変えられる。 チュートリアルの通りに変更して、表示を確認しておく。
3.3
テストだ。10年前に触ったときは、まだRSpecは生まれたてホヤホヤだった。なので、Railsのテスト周りはなんもしらない。
自動生成されたコントローラーのテストはこうなってる。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 end test "should get help" do get static_pages_help_url assert_response :success end end
全然意味わからない。いや、やりたいことの意味はわかるけど、getは何をするメソッドで、static_pages_home_urlってどこで作られるの?まあ、別にこれに限った話じゃないんだけど。
とりあえず、グリーンであることを確かめる。アプリのトップでテストを実行してみよう。
> bundle exec rails test /Users/tambara/study/rails_study/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/tambara/study/rails_study/sample_app/config/application.rb to limit the frameworks that will be loaded. Run options: --seed 49031 # Running: .. Finished in 0.642428s, 3.1132 runs/s, 3.1132 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
まだDBがありまへんけど?とツッコミが入るが、実行は出来る。何が実行されたのかさっぱりわからないので、指定してみる。
> bundle exec rails t test/controllers/static_pages_controller_test.rb /Users/tambara/study/rails_study/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/tambara/study/rails_study/sample_app/config/application.rb to limit the frameworks that will be loaded. Run options: --seed 49255 # Running: .. Finished in 0.536100s, 3.7306 runs/s, 3.7306 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
テストが一個しかないのか、おんなじだった。まあ、実行の仕方はこれでいいんだろう。
チュートリアルに従って、HelpをコピってAboutのテストを作って、レッドにしてみる。
> bundle exec rails t test/controllers/static_pages_controller_test.rb /Users/tambara/study/rails_study/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/tambara/study/rails_study/sample_app/config/application.rb to limit the frameworks that will be loaded. Run options: --seed 20205 # Running: E.. Finished in 0.615610s, 4.8732 runs/s, 3.2488 assertions/s. 1) Error: StaticPagesControllerTest#test_should_get_about: NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x00007ff1784b0cf0> test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>' 3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
static_pages_about_urlなんか知らんと言っている。うん私もしらん。
これはルーティングをセットすれば良いらしい。
Rails.application.routes.draw do get 'static_pages/home' get 'static_pages/help' get 'static_pages/about' root 'application#hello' end
もう一度、テストしてみる。
> bundle exec rails t test/controllers/static_pages_controller_test.rb (略) # Running: ..E Finished in 0.563292s, 5.3258 runs/s, 3.5506 assertions/s. 1) Error: StaticPagesControllerTest#test_should_get_about: AbstractController::ActionNotFound: The action 'about' could not be found for StaticPagesController test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'
アクションがないと言ってる。ということは、static_pages_about_urlは見つかったのかな?
とりあえず、アクション足して再実行。
> bundle exec rails t test/controllers/static_pages_controller_test.rb (略) # Running: .E. Finished in 0.709277s, 4.2297 runs/s, 2.8198 assertions/s. 1) Error: StaticPagesControllerTest#test_should_get_about: ActionController::UnknownFormat: StaticPagesController#about is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot. test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>' 3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
missing a templateって言ってる。そうだね。app/views/static_pages/about.html.erbを作ってやろう。touchで空のファイルを作る。さて、またテスト。
> bundle exec rails t test/controllers/static_pages_controller_test.rb (略) # Running: ... Finished in 0.600782s, 4.9935 runs/s, 4.9935 assertions/s. 3 runs, 3 assertions, 0 failures, 0 errors, 0 skips
グリーンになった。