Railsチュートリアル 第2章 2.3 Micropostsリソース
2.3 Micropostsリソース
・Usersリソースと同様に、Micropostリソースをscaffoldで作る。
・Micropostリソースは、以下のようなものだった。
id | integer | ポストID |
---|---|---|
text | string | ポストの内容 |
user_id | integer | 投稿したユーザーのID |
2.3.1 マイクロポストを探検する
・Usersリソース同様に、scaffoldコマンドを使ってMicropostsリソースを作る。
rails generate scaffold Micropost content:text user_id:integer
・migrationも忘れずに。
rails db:migrate
・MicropostsリソースはUsersリソースととても似ていて、micropost_controller.rb、micropost.rbを持つ。
2.3.2 マイクロポストをマイクロにする
・投稿に140字の制限を設ける。Railsのvalidatesを使う。指定したメンバ変数に制限を設けることができる。
class Micropost < ApplicationRecord validates :content, length: { maximum: 140 } end
2.3.3 ユーザーはたくさんマイクロポストを持っている
・Railsにおいては、異なるデータモデルの関係性をかんたんに実現することができる。今回の場合、Userは複数のMicropostを持ち(has_many)、Micropostは一人のUserに帰属する(belongs_to)、という関係である。UserクラスとMicropostクラスを以下のように編集する。
class User < ApplicationRecord has_many :microposts end
class Micropost < ApplicationRecord belongs_to :user validates :content, length: { maximum: 140 } end
・rails consoleコマンドを使って、アプリケーションを対話的に操作することができる。メンバ変数などを指定すると、そいつの内容とかが見れる。
2.3.4 継承の階層
・UserクラスとMicropostクラスはいずれもApplicationRecordクラスというRailsのクラスを継承している。また、ApplicationRecordはActiveRecord::Baseという基本クラス(ActiveRedordというモジュールのBaseクラス)を継承している。ActiveRecordは平たく言うとRubyとデータベースなどの翻訳機で、本当だったらSQLとかで書かないとデータベースと更新できないところを、Rubyの書き方でいいようにしてくれてるやつ。
qiita.com
・UsersControllerクラスとMicropostsControllerクラスも同様に、同じApplicationControllerクラスを継承している。また、ApplicationControllerクラスはActionController::Baseを継承している。
2.3.5 アプリケーションをデプロイする
・Github,HerokuにそれぞれPushする。
git push
・HerokuにPushしたあと、Herokuにはまだデータベースができていないので、migrationするのを忘れずに。
git push heroku heroku run rails db:migrate
Railsチュートリアル 第2章 2.2 Usersリソース
2.2 Usersリソース
・2.1.1節で設定したユーザーのモデル設定と、それを表示するためのWebインターフェイスを組み合わせて「Usersリソース」を作る。
・これによって、ユーザーという概念をオブジェクトとして扱い、HTTPプロトコルに沿って作成/取得/更新/削除などの操作が行えるようになる。
・HTTPとは、"Hyper Text Transfer Protocol"の略で、Webサーバとクライアントが通信するときの手順を決めた規格のこと。簡単に言うと、ブラウザがサーバに送るリクエストの通信の規格みたいなもの?
・Usersリソースは、RoRの機能であるscaffoldジェネレータを使って作る。できたコードを理解する必要はない。
・scaffoldとは「足場」の意味で、家を建てるときに組む足場のこと。データの雛形を簡単に作成するコマンドみたいなもの?
・scaffoldコマンドを作るときには、以下のように、リソース名を指定し、属性(メンバ変数)の名前と型を指定しておく。なお、id:integerはデフォルトでついてくるので指定する必要はない。
$ rails generate scaffold User name:string email:string Running via Spring preloader in process 4145 invoke active_record create db/migrate/20200409173002_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
・次に、データベースのマイグレートという作業をする必要がある。今、確かにUsersリソースの雛形はできたが、実際にユーザーに登録してもらった内容はデータベースとしてSQLなどで管理する必要があり、このままでは使えない。リソースからデータベースを自動で作ってくれる機能がマイグレーションで、作ったモデルをデータベースの形になおしてくれる。
www.transnet.ne.jp
$ rails db:migrate == 20200409173002 CreateUsers: migrating ====================================== -- create_table(:users) -> 0.0015s == 20200409173002 CreateUsers: migrated (0.0020s) =============================
2.2.1 ユーザーページを探検する
・ここまでやると、プレビューでUserの登録/表示/編集/削除ができるようになる。例のごとくプレビューをブラウザの方で開くと未だ"hello, world!"と表示されるが、そのURLに/usersをつけてみると全ユーザーを表示するページが開ける。/usersが全ユーザーの表示 index、/users/1がid:1のユーザーの表示 show、/users/1/editがid:1のユーザーの編集の edit,/users/newが新規ユーザーの作成 newというアクションにそれぞれ対応している。
・演習
Q1.User was successfully createdの文章のCSSはどうなっている?リロードするとどうなる?
A1.
User was successfully created.
からに変化した。つまり、動的にページが作成されている。Q2.email欄を空白にしてユーザーを作るとどうなる?
A2.Emailに値を持たないUserが作られる。
Q3.正しくないEmailを入力するとどうなる?
A3.そのまま登録される。つまり、ユーザー名の重複、不正なアドレス、Name/Emailのヌケをチェックする機能をつけなければならない。
Q4.上記のユーザーを削除するとなんと言われる?
A4.User was successfully destroyed.
2.2.2 MVCの挙動
・ここまで、scaffoldジェネレータによってUsersリソースが作成されていることは確認できた。実際これがどのように動いているのかを、MVCの挙動を見て理解する。
①ブラウザが/usersというURLのリクエストをRailsサーバーに送る。(ブラウザ→routes.rb)
②routerがリクエストを受け取り、routerによってControllerのindexアクションに割り当てられる。(routes.rb→users_controller.rb)
③indexアクションが実行され、Users Modelに「すべてのユーザーを取り出せ」と指令がいく。(users_controller.rb→users.rb)
④Users Modelが問い合わせを受け、すべてのユーザーをデータベースから取り出す。(users.rb→データベース→users.rb)
⑤ユーザーのデータがUsers ModelからUsers Controllerに渡される。(users.rb→users_controller.rb)
⑥Users Controllerがデータを@users変数(インスタンス変数)に保存し、index Viewに渡す。(users_controller.rb→index.html.erb)
⑦index Viewが起動し、Embed Ruby:ERBに沿ってページをレンダリングして、Users Controllerに返す。(index.html.erb→users_controller.rb)
⑧Users Controllerがページをブラウザに渡す。(users_controller.rb→ブラウザ)
・ルートのページを、hello,からindexに変えたい。そのためにはroutes.rbを以下のように編集すればよい。
Rails.application.routes.draw do resources :users root "users#index" end
・users_controller.rbにある各メソッドは、RESTアーキテクチャというrubyの設計思想を構成する全アクションである。RESTとは"REpresentational State Transfer"の略であり、Webアプリケーションを構成するコンポーネントを「リソース」として扱うというもの。リソースは標準でCreate/Read/Update/Delete(CRUD)の4つのアクションと、POST/GET/PATCH/DELETEの基本的な4つのHTTPリクエストに対応している。要はオブジェクト指向で全オブジェクトがもともと4つのアクションを持っている感じ?
HTTPリクエスト URL アクション 用途 GET /users index すべてのユーザーを一覧するページ GET /users/1 show id=1のユーザーを表示するページ GET /users/new new 新規ユーザーを作成するページ POST /users create ユーザーを作成するアクション GET /users/1/edit edit id=1のユーザーを編集するページ PATCH /users/1 update id=1のユーザーを更新するアクション DELETE /users/1 destroy id=1のユーザーを削除するアクション
・演習
Q1.user/1/editのリクエストが送られたときの処理の図は?
A1.
Q2.どのコードがユーザーデータを取得している?
A2.順番に見ていく。まず、Controllerのusers_controller.rbのeditメソッドには何も書かれていない。(これでどうやってmodelに命令だしてるの?)次に、Modelのuser.rbも、ApplicationRecordクラスをそのまま継承したUserクラスがあるだけなので、editはApplicationRecordクラスにあるメソッドだと思う。最後にViewのedit.html.erbを見ると、以下のようになっている。
<h1>Editing User</h1> <%= render 'form', user: @user %> <%= link_to 'Show', @user %> | <%= link_to 'Back', users_path %>
これを見ると、editのページでは、formページをレンダリングし、ShowとBackの2つのリンクを作ることになっている。formに対し引数として?userインスタンスを@userで渡している。そこでformを作ってそうな、_form.html.erbを見てみる。
<%= form_with(model: user, local: true) do |form| %> <% if user.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2> <ul> <% user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= form.label :name %> <%= form.text_field :name, id: :user_name %> </div> <div class="field"> <%= form.label :email %> <%= form.text_field :email, id: :user_email %> </div> <div class="actions"> <%= form.submit %> </div> <% end %>
上半分はエラー処理なので、下半分がフォームの本体。渡された@userのnameとemailを表示している。ここまでの作業で、ユーザーのデータを取得しているのはControllerで、その時の命令は、indexのときと違い「id:1のユーザーを取得しろ」となっているはずである。しかしeditメソッドには何も書かれていない。このことから、UsersControllerの親クラスであるApplicationControllerのeditメソッドが、デフォルトで「id:nのユーザーデータを指定しろ」となっているはずである。
Q3.ユーザーの情報を編集するページのファイル名は?
A3.上記のように、edit.html.erb。
2.2.3 Usersリソースの欠点
・このようにscaffoldジェネレータは簡単にモデルを作成できるが、このままでは以下のような問題がある。
・エラー処理がない(名前やメアドを空欄にした場合など)
・ユーザー認証がない(IDとパスワードでログインしないで、誰でも他のユーザーの情報をいじれてしまう)
・テストが書かれていない?(テストとは?)
・デザインに一貫性がない。
・コードが読みづらい。
Railsチュートリアル 第2章 2.1 アプリケーションの計画
第2章 Toyアプリケーション
・railsには簡単にアプリケーションを作るためのscaffoldジェネレータというスクリプトがある。これを通してToyアプリケーションを作り、railsの仕組みとかを大雑把にまず学ぶ。
・学ぶことは、Railsアプリの構造と、RESTアーキテクチャについて。
2.1 アプリケーションの計画
・いままでのhelllo_appじゃない、新しいアプリを作る。
$ rails _5.1.6_ new toy_app
・前と同じように、Gemfileの編集、bundle install, gitの設定、herokuの設定を行いデプロイまでやる。これで準備完了。
2.1.1 ユーザーのモデル設計
・今から作るのは、小さいツイッターみたいなもの。
・マイクロブログを作るためには、ユーザーを管理する必要がある。今回は一番単純な、id, name, emailの3つのデータのセットを1ユーザーとして扱う。rubyのテーブル型を使っている?
データ | 型 | 説明 |
---|---|---|
id | integer | ユーザーID |
name | string | 表示する名前 |
string | メアド |
マイクロソフトのモデル設計
・同様に、id,text,user_idの3つのデータを一つのポストとして扱う。
id | integer | ポストID |
---|---|---|
text | string | ポストの内容 |
user_id | integer | 投稿したユーザーのID |
Railsチュートリアル 第1章 1.5 デプロイする
1.5.1 Herokuのセットアップ
・今、作ったアプリがあるのはローカルとGithub上だけなので、このままではユーザーに公開できない。
・公開するためには外部にデプロイする必要がある。Herokuはそのクラウドサービスの名前。
・HerokuはPostgreSQLというデータベースでコンテンツを管理している。そのため、RailsとPostgreSQLとの通信に使うgemであるpgを用いる。
・Gemfileを変更し、以下の文言を追加する。
group :production do gem "pg", "0.20.0" end
・次にbundle install --without production で、Gemfile.lockに変更を適用する。pgはローカル環境では使わないので、ローカルにはインストールされないが、こうしておかないと本番環境へのデプロイに失敗する。
・最後にgit commitをしてコミットする。
・次にherokuをインストールする。
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)
・AWSにログインし直すたびにherokuコマンドがないと言われるらしい。これはPATHの設定が間違っていることが原因?らしく、.bash_profileというファイルを作成し、以下のように書き込む。
PATH=/usr/local/heroku/bin:$PATH
qiita.com
・インストールが完了したら、IDとパスワードでHerokuにログインする。
$ heroku rogin --interactive heroku: Enter your login credentials Email: Password:
・次に、heroku側にappを入れておくリポジトリ?を作る。
heroku create
・最後に、デプロイする。デプロイはpushすればできる。
git push heroku master
・createしたときにできたURLを開くと、ちゃんとデプロイされているのがわかる。
https://mysterious-ocean-23441.herokuapp.com/
演習
Q1.本番アプリでも"hola, mundo!"を表示する。
A1. ①application_controller.rbにアクションhelloがあることを確認する。
②routes.rbを編集し、helloを実行するように変える。
③git commit -aでコミットし、, git push heroku masterで変更をherokuにデプロイする。
Q2.本番アプリで"goodbye,world!"を表示する。
A2. ①application_controller.rbにアクションgoodbyeがあることを確認する。
②routes.rbを編集し、goodbyeを実行するように変える。
③git commit -aでコミットし、, git push heroku で変更をherokuにデプロイする。(masterを省略しても大丈夫)
1.5.4 Herokuコマンド
・heroku rename A でappの名前を変えられる。
・heroku logs でログが見られる。
・一覧は以下。
VERSION heroku/7.39.2 linux-x64 node-v12.13.0 USAGE $ heroku [COMMAND] COMMANDS access manage user access to apps addons tools and services for developing, extending, and operating your app apps manage apps on Heroku auth check 2fa status authorizations OAuth authorizations autocomplete display autocomplete installation instructions base buildpacks scripts used to compile apps certs a topic for the ssl plugin ci run an application test suite on Heroku clients OAuth clients on the platform config environment variables of apps container Use containers to build and deploy Heroku apps domains custom domains for apps drains forward logs to syslog or HTTPS features add/remove app features git manage local git repository for app help display help for heroku keys add/remove account ssh keys labs add/remove experimental features local run Heroku app locally logs display recent log output maintenance enable/disable access to app members manage organization members notifications display notifications orgs manage organizations pg manage postgresql databases pipelines manage pipelines plugins list installed plugins ps Client tools for Heroku Exec psql open a psql shell to the database redis manage heroku redis instances regions list available regions for deployment releases display the releases for an app reviewapps manage reviewapps in pipelines run run a one-off process inside a Heroku dyno sessions OAuth sessions spaces manage heroku private spaces status status of the Heroku platform teams manage teams update update the Heroku CLI webhooks list webhooks on an app
Railsチュートリアル 第1章 1.4 Gitによるバージョン管理
1.4.1 インストールとセットアップ
・gitはもともとIDEに入っている。以下の手順でセットアップを行う。
①gitをインストールしたとき、初回だけsystemセットアップと呼ばれる設定をする必要がある。
$ git config --global user.name "Your Name" $ git config --global user.email your.email@example.com
ここで設定した名前とメールアドレスは、リポジトリ上で公開されるのでちゃんとしたのをつけよう。
②git initでリポジトリを初期化しておく。よくわからないけど。
③git add -A をし、現在のディレクトリにあるファイルをすべてgitに追加する。この段階ではまだ保存されていない。安全のためすぐにコミットはされず、ステージングという一時待機の状態になっている。ステージングされているファイルを確認するためには、git status コマンドを用いる。
④git commit を用い、ステージングされていた(保留されていた)ファイルをコミットする。このとき、-mをつけるとメッセージを指定できる。
$ git commit -m "Initialize repository" [master (root-commit) df0a62f] Initialize repository
⑤ここまででコミットされたが、これはあくまでローカルマシン上のgitに保存されたにすぎない。共有のサーバーとかに保存するためにはpushをする必要がある。(1.4.4説で解説)
1.4.2 Gitのメリット
・Gitを使っておけば、例えば間違えて重要なファイルをrmしてしまったとしても、checkoutを使えばもとに戻せたりする。
1.4.3 Bitbucket(Github)
・ローカルに入ってるリポジトリをpushして公開/共有するためのWebサービスのこと。
・使うにはまずSSH公開鍵を作成し、Githubに登録しておく必要がある。SSHとはSecure Shellの略語で、安全な通信の規格名。パスワード方式と公開鍵方式がある。
(qiita.com)
・SSH公開鍵はssh-keygenで作成し、cat id_rsa.pubで確認できる。
$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/ec2-user/.ssh/id_rsa. Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub. The key fingerprint is:~~~~ $ cat id_rsa.pub
・作った公開鍵をGithubに登録したら、 ssh -T git@github.com で接続を確認できる。
・リポジトリをプッシュするためには、まずGithubをプッシュ先として登録する。
$ git remote add origin git@github.com:(ユーザー名)/(リポジトリ名).git
・次にプッシュする。
$ git push -u origin master
・Gitの優れた点は、ブランチ機能にある。枝分かれ(ブランチ)を作成し、元のファイルを変更せずに編集できる。
①git checkout -b (ブランチ名) でブランチを作成できる。ブランチの状態は git branch で確認できる。git checkout はブランチ間の移動コマンドでもある。
$ git checkout -b modify-README $ git branch master * modify-README
②編集を行い、 git statusで確認をする。その後、git commit でコミットをする。変更したファイルすべてをコミットするには -a を、メッセージをつけるには -m "メッセージ" を使う。また、新しいファイルを作成した場合は、先にgit Add をしないとそのファイルがリポジトリに追加されない。
$ git status On branch modify-README 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: README.md $ git commit -a -m "Improve the README file" [modify-README 237aaee] Improve the README file
no changes added to commit (use "git add" and/or "git commit -a")
③ここまでの変更はすべてブランチ上で行われたものである。これをマスターブランチにマージする必要があり、git checkout master でマスターに移動してから git merge を用いる。
$ git checkout master Switched to branch 'master' $ git merge modify-README Updating 7f43922..237aaee Fast-forward README.md | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-)
④最後に、もしサブブランチが不要になれば、git branch -d で削除する。
$ git branch -d modify-README Deleted branch modify-README (was 237aaee).
または、git branch -D を使うと、ブランチ上の変更を全て破棄し、ブランチを消せるが、ミスしたときに使うべし。
Railsチュートリアル 第1章 1.3 最初のアプリケーション
- 1.3 最初のアプリケーション
- 1.3.1 Bundler
- 1.3.2 rails server
- 1.3.3 Model-View-Controller(MVC)
- 1.3.4 Hello,World!
1.3 最初のアプリケーション
・HelloWorldを作る。
・Unixコマンドまとめ
ls 現在のディレクトリ内容の表示
mkdir NAME ディレクトリの作成
cd ディレクトリの移動(cd..で上、cd~でホーム)
mv A Bファイルの移動とリネーム
cp A B ファイルのコピー
rm A ファイルの削除
rmdir A 空のディレクトリの削除
rm -rf A 中身のあるディレクトリの削除
cat A ファイル内容の結合と表示
・アプリケーション作成の手順
①rails newを実行する。Railsのバージョンをインストールしたものと合わせる。
言われたこと:
HEADS UP! i18n 1.1 changed fallbacks to exclude default locale.
But that may break your application.
If you are upgrading your Rails application from an older version of Rails:
Please check your Rails app for 'config.i18n.fallbacks = true'.
If you're using I18n (>= 1.1.0) and Rails (< 5.2.2), this should be
'config.i18n.fallbacks = [I18n.default_locale]'.
If not, fallbacks will be broken in your app by I18n 1.1.x.
If you are starting a NEW Rails application, you can ignore this notice.
For more info see:
https://github.com/svenfuchs/i18n/releases/tag/v1.1.0
Post-install message from sass:
Ruby Sass has reached end-of-life and should no longer be used.
* If you use Sass as a command-line tool, we recommend using Dart Sass, the new
primary implementation: https://sass-lang.com/install
* If you use Sass as a plug-in for a Ruby web framework, we recommend using the
sassc gem: https://github.com/sass/sassc-ruby#readme
* For more details, please refer to the Sass blog:
https://sass-lang.com/blog/posts/7828841
run bundle exec spring binstub --all
* bin/rake: Spring inserted
* bin/rails: Spring inserted
bundle installが勝手に実行されるらしい。また、このように生成されたファイル
構造は、RoRにおいて標準化されたもの。
1.3.1 Bundler
・さっきのコマンドで、Bundlerというものがついでにインストールされた。
・Bundelerを使ってgemをインストールできる。
・gemのインストールのために、Gemfileに記述をしておく必要がある。Gemfileに
は、Bundlerによってインストールされるgemの名前とバージョンが指定されて
いる。
・Gemfileのバージョン指定の仕方は、①バージョンの数字を固定し、そのバージョ
ンのみを使う方法と、②バージョンを範囲指定し自動でアップデートする方法の
2つがある。
①gem "A", "5.1.6"
②gem "A", ">=1.3.0" :ver1.3.0以上のものがあれば自動でアップデート
gem "A", "~>5.0" ver5.0~5.9までがあれば自動でアップデート、6.xなどは使わない
・Gemfileに必要なgemとそのバージョンの記述をし終えたら、コマンドライン
でbundle install を実行し、gemをinstallする。
・bundle updateを先に実行しろと言われたので、した。
1.3.2 rails server
・RoRには、テスト用のローカルサーバーを立ち上げるコマンド rails server がつ
いている。
・rails server を実行した後、C9のPreview>Preview Running Applicationを押すとブラ
ウザが開く。C9のブラウザでは「接続が拒否されました」と表示されるが、右
上の"Pop out into new window"を選択すると新しいタグで開け、railsが動いている
のを確認できる。
・演習
Q1:Railsのページ上でのrubyのバージョンと、コマンド ruby -v で確認できる開発
環境のバージョンはどうなっている?
A1:一致している。2.6.3。
Q2:Railsのバージョンは?
A2:同じく一致している。
1.3.3 Model-View-Controller(MVC)
・RoRはModel-View-Controllerというアーキテクチャパターン(設計の種類)を採用し
ている。MVCでは、データとデータを表示するソースコードが分離してファイルに
収められているということ。要するに大体のゲームとかとで、プログラム部分と画
像とかマップとかアイテムの数値とかがわけられている感じ。
・ブラウザがリクエストをControllerに送り、ControllerはModelを介してデータベー
スなどからデータを受け取りViewを作る。そのViewをブラウザに渡してユーザーに
ページが表示される、という役割分担をMVCで果たしている。
1.3.4 Hello,World!
・今の空のアプリケーションに、Hello,World!と表示するアクション(命令みたいな
もの)を追加したい。
・これはMVCの中でいうとControllerの仕事なので、
app/controllers/application_controller にアクションを追加する。
・以下の文言を追加する。関数の定義みたいなもの。
def hello render html: "hello, world!" end end
・renderはテキストを表示するメソッド。
・アクションを追加しただけでは実行されない。controllerがどのアクションを実行す
ればいいかの司令のファイルである、routerを編集してデフォルトのアクションの
代わりにhelloを実行してくれるようにする必要がある。routerファイルは、
config/routersである。アクションを追加する場合、
Rails.application.routes.draw do root 'application#hello' end
のように記述する。
・まとめると、新しいアクションを追加するためには、
①Controllerに新しいアクションを定義する。
②routerにそのアクションを実行するタイミング?場所?を定義する。