2章はscaffoldを使ってみるらしい。
さて、前回Railsのバージョンでかなりヒドい目に遭って、訳がわからなくなった。 恐らくは、rails newしたタイミングではbundle installが走ってはいけないのだと思う。 こんな記事もある
rails new でバージョン指定したのに上のバージョンになって困った話 - のえら
うん、たぶんそうすれば良かったんだな。
というか、このお勉強用ディレクトリのvendor/bundleにRailsのgemを入れるんであれば、最初から5.1.6をいれろやという話かもしれない。
なので、乱暴かもしれないが、お勉強用ディレクトリをrm -fr ./*
して、Railsを入れ直すところからやることにする。
> bundle init Writing new Gemfile to /Users/tambara/study/rails_study/Gemfile > vi Gemfile > cat Gemfile # frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "rails", '5.1.6'
念のため、ここでもバージョンを指定しておこう。
> bundle install --path=vendor/bundle Fetching gem metadata from https://rubygems.org/.......... Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Fetching rake 12.3.1 Installing rake 12.3.1 Fetching concurrent-ruby 1.1.3 Installing concurrent-ruby 1.1.3 Fetching i18n 1.1.1 Installing i18n 1.1.1 Fetching minitest 5.11.3 Installing minitest 5.11.3 Fetching thread_safe 0.3.6 Installing thread_safe 0.3.6 Fetching tzinfo 1.2.5 Installing tzinfo 1.2.5 Fetching activesupport 5.1.6 Installing activesupport 5.1.6 Fetching builder 3.2.3 Installing builder 3.2.3 Fetching erubi 1.7.1 Installing erubi 1.7.1 Fetching mini_portile2 2.3.0 Installing mini_portile2 2.3.0 Fetching nokogiri 1.8.5 Installing nokogiri 1.8.5 with native extensions Fetching rails-dom-testing 2.0.3 Installing rails-dom-testing 2.0.3 Fetching crass 1.0.4 Installing crass 1.0.4 Fetching loofah 2.2.3 Installing loofah 2.2.3 Fetching rails-html-sanitizer 1.0.4 Installing rails-html-sanitizer 1.0.4 Fetching actionview 5.1.6 Installing actionview 5.1.6 Fetching rack 2.0.6 Installing rack 2.0.6 Fetching rack-test 1.1.0 Installing rack-test 1.1.0 Fetching actionpack 5.1.6 Installing actionpack 5.1.6 Fetching nio4r 2.3.1 Installing nio4r 2.3.1 with native extensions Fetching websocket-extensions 0.1.3 Installing websocket-extensions 0.1.3 Fetching websocket-driver 0.6.5 Installing websocket-driver 0.6.5 with native extensions Fetching actioncable 5.1.6 Installing actioncable 5.1.6 Fetching globalid 0.4.1 Installing globalid 0.4.1 Fetching activejob 5.1.6 Installing activejob 5.1.6 Fetching mini_mime 1.0.1 Installing mini_mime 1.0.1 Fetching mail 2.7.1 Installing mail 2.7.1 Fetching actionmailer 5.1.6 Installing actionmailer 5.1.6 Fetching activemodel 5.1.6 Installing activemodel 5.1.6 Fetching arel 8.0.0 Installing arel 8.0.0 Fetching activerecord 5.1.6 Installing activerecord 5.1.6 Using bundler 1.17.1 Fetching method_source 0.9.2 Installing method_source 0.9.2 Fetching thor 0.20.3 Installing thor 0.20.3 Fetching railties 5.1.6 Installing railties 5.1.6 Fetching sprockets 3.7.2 Installing sprockets 3.7.2 Fetching sprockets-rails 3.2.1 Installing sprockets-rails 3.2.1 Fetching rails 5.1.6 Installing rails 5.1.6 Bundle complete! 1 Gemfile dependency, 38 gems now installed. Bundled gems are installed into `./vendor/bundle` > rails -v Rails 5.2.1 > which rails /Users/tambara/.rbenv/shims/rails > bundle exec rails -v Rails 5.1.6
あ、.ruby-versionも消えてしまったはずだ。
遅ればせながら、rbenv local 2.5.1
もやり直しておく。
では、チュートリアルの2章の先頭からやっていこう
> bundle exec rails _5.1.6_ new toy_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/toy_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
リスト2.1にGemfileを書き換えて、bundle install
する
> cd toy_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.11.3 Using thread_safe 0.3.6 Using tzinfo 1.2.5 Fetching activesupport 5.1.6 Installing 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 Fetching actionview 5.1.6 Installing actionview 5.1.6 Using rack 2.0.6 Using rack-test 1.1.0 Fetching actionpack 5.1.6 Installing actionpack 5.1.6 Using nio4r 2.3.1 Using websocket-extensions 0.1.3 Fetching websocket-driver 0.6.5 Installing websocket-driver 0.6.5 with native extensions Fetching actioncable 5.1.6 Installing actioncable 5.1.6 Using globalid 0.4.1 Fetching activejob 5.1.6 Installing activejob 5.1.6 Using mini_mime 1.0.1 Using mail 2.7.1 Fetching actionmailer 5.1.6 Installing actionmailer 5.1.6 Fetching activemodel 5.1.6 Installing activemodel 5.1.6 Fetching arel 8.0.0 Installing arel 8.0.0 Fetching activerecord 5.1.6 Installing activerecord 5.1.6 Using bindex 0.5.0 Using bundler 1.17.1 Fetching byebug 9.0.6 Installing byebug 9.0.6 with native extensions 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 Fetching railties 5.1.6 Installing railties 5.1.6 Using coffee-rails 4.2.2 Using ffi 1.9.25 Using multi_json 1.13.1 Fetching jbuilder 2.7.0 Installing jbuilder 2.7.0 Fetching jquery-rails 4.3.1 Installing jquery-rails 4.3.1 Using rb-fsevent 0.10.3 Using rb-inotify 0.9.10 Using ruby_dep 1.5.0 Using listen 3.1.5 Fetching puma 3.9.1 Installing puma 3.9.1 with native extensions Using sprockets 3.7.2 Using sprockets-rails 3.2.1 Fetching rails 5.1.6 Installing rails 5.1.6 Using sass-listen 4.0.0 Using sass 3.7.2 Using tilt 2.0.8 Fetching sass-rails 5.0.6 Installing 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 Fetching turbolinks 5.0.1 Installing turbolinks 5.0.1 Fetching uglifier 3.2.0 Installing uglifier 3.2.0 Fetching web-console 3.5.1 Installing web-console 3.5.1 Bundle complete! 15 Gemfile dependencies, 64 gems now installed. Gems in the group production were not installed. Use `bundle info [gemname]` to see where a bundled gem is installed.
あ、また~/.rbenvの下に入っちゃった。どうもよくわからないな・・・。まあ、しょうがない。続き。
> git add -A > git commit -m 'Initialize repository' (略) > vi app/controllers/application_controller.rb > vi config/routes.rb > git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: app/controllers/application_controller.rb modified: config/routes.rb no changes added to commit (use "git add" and/or "git commit -a") > git add --all > git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: app/controllers/application_controller.rb modified: config/routes.rb > git commit -m 'Add hello' [master b08b557] Add hello 2 files changed, 5 insertions(+), 1 deletion(-) > heroku create Creating app... done, ⬢ sleepy-tundra-20972 https://sleepy-tundra-20972.herokuapp.com/ | https://git.heroku.com/sleepy-tundra-20972.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.00 KiB | 1.67 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.11.3 remote: Installing rake 12.3.1 remote: Installing minitest 5.11.3 remote: Installing concurrent-ruby 1.1.3 remote: Fetching thread_safe 0.3.6 remote: Fetching builder 3.2.3 remote: Installing builder 3.2.3 remote: Installing thread_safe 0.3.6 remote: Fetching erubi 1.7.1 remote: Installing erubi 1.7.1 remote: Fetching mini_portile2 2.3.0 remote: Installing mini_portile2 2.3.0 remote: Fetching crass 1.0.4 remote: Installing crass 1.0.4 remote: Fetching rack 2.0.6 remote: Installing rack 2.0.6 remote: Fetching nio4r 2.3.1 remote: Fetching websocket-extensions 0.1.3 remote: Installing nio4r 2.3.1 with native extensions remote: Installing websocket-extensions 0.1.3 remote: Fetching mini_mime 1.0.1 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: Installing execjs 2.7.0 remote: Fetching method_source 0.9.2 remote: Installing method_source 0.9.2 remote: Fetching thor 0.20.3 remote: Installing thor 0.20.3 remote: Fetching ffi 1.9.25 remote: Fetching multi_json 1.13.1 remote: Installing multi_json 1.13.1 remote: Fetching pg 0.20.0 remote: Installing ffi 1.9.25 with native extensions 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 actionmailer 5.1.6 remote: Fetching railties 5.1.6 remote: Fetching actioncable 5.1.6 remote: Installing actionmailer 5.1.6 remote: Installing actioncable 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 rails 5.1.6 remote: Fetching coffee-rails 4.2.2 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! 15 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.69s) 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-21T07:21:47.419386 #1376] INFO -- : Writing /tmp/build_a47d32405f236aed0cca858ff64dcf0e/public/assets/application-7e084e44b9a13db0cda25bad2ac6fdbbfe31462ec93176e245cd0bcbc079f436.js remote: I, [2018-11-21T07:21:47.420053 #1376] INFO -- : Writing /tmp/build_a47d32405f236aed0cca858ff64dcf0e/public/assets/application-7e084e44b9a13db0cda25bad2ac6fdbbfe31462ec93176e245cd0bcbc079f436.js.gz remote: I, [2018-11-21T07:21:47.425870 #1376] INFO -- : Writing /tmp/build_a47d32405f236aed0cca858ff64dcf0e/public/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css remote: I, [2018-11-21T07:21:47.426144 #1376] INFO -- : Writing /tmp/build_a47d32405f236aed0cca858ff64dcf0e/public/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css.gz remote: Asset precompilation completed (2.70s) 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: 41.1M remote: -----> Launching... remote: Released v6 remote: https://sleepy-tundra-20972.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/sleepy-tundra-20972.git * [new branch] master -> master
おー、今度はエラーにならなかった。よしよし。つか、ここまでは1章と何も変わらない。
さて、scaffoldはデータモデルからえいやっとする方法なので、データモデルを作る。10年前にRailsをちょっとだけ勉強したときには普通にCREATE TABLEしてそこから作ってた気がするけど、もうそういう時代ではないらしい。
> bundle exec rails generate scaffold User name:string email:string invoke active_record create db/migrate/20181121083708_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources :users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder create app/views/users/_user.json.jbuilder invoke test_unit create test/system/users_test.rb invoke assets invoke coffee create app/assets/javascripts/users.coffee invoke scss create app/assets/stylesheets/users.scss invoke scss create app/assets/stylesheets/scaffolds.scss > bundle exec rails db:migrate == 20181121083708 CreateUsers: migrating ====================================== -- create_table(:users) -> 0.0009s == 20181121083708 CreateUsers: migrated (0.0010s) =============================
作る順番が逆転してるわー。
rails newしてからDBの設定なんかしていないわけだけども、デフォルトがSQLiteになっているようだ。config/database.ymlをみるとそう書いてある。で、DBが作られた訳ね、どこかに。というか、database.ymlによれば、db/development.sqlite3ですな。
> ls db development.sqlite3 migrate schema.rb seeds.rb
さて、この段階でrails server
してscaffoldで出来たUserの画面を見てみよう。
> bundle exec rails server => Booting Puma => Rails 5.1.6 application starting in development => Run `rails server -h` for more startup options Puma starting in single mode... * Version 3.9.1 (ruby 2.5.1-p57), codename: Private Caller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://0.0.0.0:3000 Use Ctrl-C to stop
これでUSERテーブルのCRUDの機能に/usersでアクセスできる。お馴染みのscaffoldだ。Railsの原点とも言える。
Railsは「Webアプリなんて所詮、ドメインモデルをそのままテーブル構造に反映させたDBへのCRUD機能でほとんどまかなえるんだ」と言い放った。もちろん、そんな簡単なアプリばかりではないけども、簡単なアプリ(それこそブログとか)ならそれで作れて、それを最速で作れるように特化したのがRailsであり、その際に使われたのがRubyのメタプログラミング(=黒魔術)だったというのが、Ruby on Railsの成り立ちである。そこから思えば遠くにきたものだ。
感慨にふけっていても仕方が無いので、どんどんいこう。
その前に2.2.1の演習だ。
1つ目は、ユーザー作成時のメッセージを調べてみろとのことだ。
こうなってる。
リロードすると、<p id="notice">
の中身は消える。
app/views/users/show.html.erbを見ると、
<p id="notice"><%= notice %></p>
となっている。
app/controllers/users_controller.rbを見ると、
# POST /users # POST /users.json def create @user = User.new(user_params) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.json { render :show, status: :created, location: @user } else format.html { render :new } format.json { render json: @user.errors, status: :unprocessable_entity } end end end
こうなっているので、メッセージの元はここだ。
リロードすると呼び出されるのは
# GET /users/1 # GET /users/1.json def show end
こっちなので、何にも出ないのだと思われる。というか、空のメソッド定義を作ると何が起きるの?
さて、2つ目。名前だけで、emailを入力しないとどうなるか。普通に作られる。 テーブル定義を確認してみよう。
> sqlite3 development.sqlite3 SQLite version 3.19.3 2017-06-27 16:48:08 Enter ".help" for usage hints. sqlite> .table ar_internal_metadata schema_migrations users sqlite> .schema users CREATE TABLE IF NOT EXISTS "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "email" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
NOT NULLじゃないのでNULLが入るのか・・・と思いきや、単に長さ0の文字列は入っているっぽい。
sqlite> SELECT name, '>' || email || '<' FROM users; 太郎冠者|>taro@ex.com< 次郎冠者|>jiro@ex.com< 三郎|><
まあ、自然だ。演習3も、別に普通に入る。validationはまだ何にもしていないんだし。
sqlite> sqlite> SELECT name, '>' || email || '<' FROM users; 太郎冠者|>taro@ex.com< 次郎冠者|>jiro@ex.com< 三郎|>< 士郎正宗|>@example.com<
演習4。削除の挙動を確認する。削除は、ダイアログが出る。 どうなっているかというと、削除のリンクはこう定義されてる。
<a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/users/3">Destroy</a>
よくわからない・・・。
ググるとこういうことらしい。
[コードリーディング] link_toの:methodと:confirmの挙動 - Qiita
な、なるほど・・・javascriptとrackの合わせ技でDELETEメソッドHTMLから送れるようにしているってことか・・・。すごいね。
2.2.2は仕組みの説明。読んで、演習に行ってみる。
演習は、/users/1/editの振る舞いの説明。編集はupdateアクション。updateはPATCHメソッドに紐づいている。 PATCHって初めて聞いた。PUTじゃないのか・・・。
/users/1/editに行くと、こんなHTMLが表示される。
<form action="/users/3" accept-charset="UTF-8" method="post"> <input name="utf8" value="✓" type="hidden"> <input name="_method" value="patch" type="hidden"> <input name="authenticity_token" value="5QWnf/p1Bjq4xi/HM12xu0gzsvS40Q9VjImgUP4sCDCrK9xq/fRn5vO1/VpT4UR167Ac858VSlZlWU6lX6KQ5Q==" type="hidden"> <div class="field"> <label for="user_name">Name</label> <input id="user_name" value="三郎" name="user[name]" type="text"> </div> <div class="field"> <label for="user_email">Email</label> <input id="user_email" value="" name="user[email]" type="text"> </div> <div class="actions"> <input name="commit" value="Update User" data-disable-with="Update User" type="submit"> </div> </form>
_method=patchを送ることにより、PATCHメソッドに変換されるようにhiddenがセットされてる。ふむふむ。
これの元になったviewはこんなerbだ。app/views/users/edit.html.erb。
<h1>Editing User</h1> <%= render 'form', user: @user %> <%= link_to 'Show', @user %> | <%= link_to 'Back', users_path %>
えええ、まじでーって感じ。上の<form>
は1行かー・・・。
さて、演習の2はUPDATE文を投げている部分はどこか探してみようの巻。updateメソッドを見れば良いはず。
# PATCH/PUT /users/1 # PATCH/PUT /users/1.json def update respond_to do |format| if @user.update(user_params) format.html { redirect_to @user, notice: 'User was successfully updated.' } format.json { render :show, status: :ok, location: @user } else format.html { render :edit } format.json { render json: @user.errors, status: :unprocessable_entity } end end end
あー、PUTでもいいらしい。UPDATEをやっているのは@user.update(user_params)
だろう。
でも、user_params
って何だろう。あ、privateなメソッドがある。
# Never trust parameters from the scary internet, only allow the white list through. def user_params params.require(:user).permit(:name, :email) end
セキュリティ的にちゃばいかもよというコメントがついている。親切だ。 しかし、このメソッドを見ても何にもわからないな・・・。 まあ、おそらくparamsはリクエストのパラメータすべてで、そこからuser[:name]とuser[:email]だけを 選んだものを返すということなんだろう。たぶん。
3は上でもう答えたので完了。
2.2.3はさらっと読んで終わり。validationとtestとdesignがなく、意味もわからないから困るねと書いてある。 「scaffoldのコードを理解できるぐらいなら、そもそも本書を読む必要はないでしょう」ごもっとも。