Railsチュートリアルがあまりに意味不明だったので、小休止&復習を兼ねてドットインストールの入門編のブログ作成にトライしてみようと思います。
チュートリアルをもう一回、やるつもりなので環境はチュートリアルのママでいきたく思います。
環境について
ec2-user:~/environment $ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
ec2-user:~/environment $ sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668
ec2-user:~/environment $ rails -v
Rails 5.1.7
こんな感じです。
最初のメモアプリ作成に関して
$ rails g scaffold Memo title:string body:text
スキャッフォードで簡単に生成。
きちんと生成されたものをみてみたら結構すごいのねコレ。
メモアプリは終わりで、さっそくブログアプリ
ec2-user:~/environment $ rails new myblog
create
create README.md
create Rakefile
create config.ru
create .gitignore
create Gemfile
run git init from "."
Initialized empty Git repository in /home/ec2-user/environment/myblog/.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
run bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies....
Using rake 13.0.1
Using concurrent-ruby 1.1.6
Using i18n 1.8.2
Using minitest 5.14.0
Using thread_safe 0.3.6
Using tzinfo 1.2.7
Using activesupport 5.1.7
Using builder 3.2.4
Using erubi 1.9.0
Using mini_portile2 2.4.0
Using nokogiri 1.10.9
Using rails-dom-testing 2.0.3
Using crass 1.0.6
Using loofah 2.5.0
Using rails-html-sanitizer 1.3.0
Using actionview 5.1.7
Using rack 2.2.2
Using rack-test 1.1.0
Using actionpack 5.1.7
Using nio4r 2.5.2
Using websocket-extensions 0.1.4
Using websocket-driver 0.6.5
Using actioncable 5.1.7
Using globalid 0.4.2
Using activejob 5.1.7
Using mini_mime 1.0.2
Using mail 2.7.1
Using actionmailer 5.1.7
Using activemodel 5.1.7
Using arel 8.0.0
Using activerecord 5.1.7
Fetching public_suffix 4.0.5
Installing public_suffix 4.0.5
Using addressable 2.7.0
Using bindex 0.8.1
Using bundler 1.17.3
Using byebug 11.1.3
Using regexp_parser 1.7.0
Using xpath 3.2.0
Using capybara 3.32.1
Using childprocess 3.0.0
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using coffee-script 2.4.1
Using method_source 1.0.0
Using thor 1.0.1
Using railties 5.1.7
Using coffee-rails 4.2.2
Using ffi 1.12.2
Using jbuilder 2.10.0
Using rb-fsevent 0.10.4
Using rb-inotify 0.10.1
Using ruby_dep 1.5.0
Using listen 3.1.5
Using puma 3.12.4
Using sprockets 3.7.2
Using sprockets-rails 3.2.1
Using rails 5.1.7
Using rubyzip 2.3.0
Using sass-listen 4.0.0
Using sass 3.7.4
Using tilt 2.0.10
Using sass-rails 5.0.7
Using selenium-webdriver 3.142.7
Using spring 2.1.0
Using spring-watcher-listen 2.0.1
Using sqlite3 1.4.2
Using turbolinks-source 5.2.0
Using turbolinks 5.2.1
Using uglifier 4.2.0
Using web-console 3.7.0
Bundle complete! 16 Gemfile dependencies, 70 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
run bundle exec spring binstub --all
* bin/rake: Spring inserted
* bin/rails: Spring inserted
気になるのはgitを無視して進めるかどうか。Railsチュートリアルのときはいわれるがままだったので、ここで再度、やってみようと思う。
ドットインストール入門編をgitで試してみる
再度、Railsチュートリアルの第一章をさらっと見てみる。
そしてbitbucketでリポジトリも作成して、、、
c2-user:~/environment/myblog (master) $ git init
Reinitialized existing Git repository in /home/ec2-user/environment/myblog/.git/
ec2-user:~/environment/myblog (master) $ git add -A
ec2-user:~/environment/myblog (master) $ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: Gemfile
new file: Gemfile.lock
new file: README.md
new file: Rakefile
new file: app/assets/config/manifest.js
new file: app/assets/images/.keep
new file: app/assets/javascripts/application.js
new file: app/assets/javascripts/cable.js
new file: app/assets/javascripts/channels/.keep
new file: app/assets/stylesheets/application.css
new file: app/channels/application_cable/channel.rb
new file: app/channels/application_cable/connection.rb
new file: app/controllers/application_controller.rb
new file: app/controllers/concerns/.keep
new file: app/helpers/application_helper.rb
new file: app/jobs/application_job.rb
new file: app/mailers/application_mailer.rb
new file: app/models/application_record.rb
new file: app/models/concerns/.keep
new file: app/views/layouts/application.html.erb
new file: app/views/layouts/mailer.html.erb
new file: app/views/layouts/mailer.text.erb
new file: bin/bundle
new file: bin/rails
new file: bin/rake
new file: bin/setup
new file: bin/spring
new file: bin/update
new file: bin/yarn
new file: config.ru
new file: config/application.rb
new file: config/boot.rb
new file: config/cable.yml
new file: config/database.yml
new file: config/environment.rb
new file: config/environments/development.rb
new file: config/environments/production.rb
new file: config/environments/test.rb
new file: config/initializers/application_controller_renderer.rb
new file: config/initializers/assets.rb
new file: config/initializers/backtrace_silencers.rb
new file: config/initializers/cookies_serializer.rb
new file: config/initializers/filter_parameter_logging.rb
new file: config/initializers/inflections.rb
new file: config/initializers/mime_types.rb
new file: config/initializers/wrap_parameters.rb
new file: config/locales/en.yml
new file: config/puma.rb
new file: config/routes.rb
new file: config/secrets.yml
new file: config/spring.rb
new file: db/seeds.rb
new file: lib/assets/.keep
new file: lib/tasks/.keep
new file: log/.keep
new file: package.json
new file: public/404.html
new file: public/422.html
new file: public/500.html
new file: public/apple-touch-icon-precomposed.png
new file: public/apple-touch-icon.png
new file: public/favicon.ico
new file: public/robots.txt
new file: test/application_system_test_case.rb
new file: test/controllers/.keep
new file: test/fixtures/.keep
new file: test/fixtures/files/.keep
new file: test/helpers/.keep
new file: test/integration/.keep
new file: test/mailers/.keep
new file: test/models/.keep
new file: test/system/.keep
new file: test/test_helper.rb
new file: tmp/.keep
new file: vendor/.keep
ec2-user:~/environment/myblog (master) $ git commit -m "Initialize repository"
[master (root-commit) cdc98bb] Initialize repository
76 files changed, 1196 insertions(+)
create mode 100644 .gitignore
create mode 100644 Gemfile
create mode 100644 Gemfile.lock
create mode 100644 README.md
create mode 100644 Rakefile
create mode 100644 app/assets/config/manifest.js
create mode 100644 app/assets/images/.keep
create mode 100644 app/assets/javascripts/application.js
create mode 100644 app/assets/javascripts/cable.js
create mode 100644 app/assets/javascripts/channels/.keep
create mode 100644 app/assets/stylesheets/application.css
create mode 100644 app/channels/application_cable/channel.rb
create mode 100644 app/channels/application_cable/connection.rb
create mode 100644 app/controllers/application_controller.rb
create mode 100644 app/controllers/concerns/.keep
create mode 100644 app/helpers/application_helper.rb
create mode 100644 app/jobs/application_job.rb
create mode 100644 app/mailers/application_mailer.rb
create mode 100644 app/models/application_record.rb
create mode 100644 app/models/concerns/.keep
create mode 100644 app/views/layouts/application.html.erb
create mode 100644 app/views/layouts/mailer.html.erb
create mode 100644 app/views/layouts/mailer.text.erb
create mode 100755 bin/bundle
create mode 100755 bin/rails
create mode 100755 bin/rake
create mode 100755 bin/setup
create mode 100755 bin/spring
create mode 100755 bin/update
create mode 100755 bin/yarn
create mode 100644 config.ru
create mode 100644 config/application.rb
create mode 100644 config/boot.rb
create mode 100644 config/cable.yml
create mode 100644 config/database.yml
create mode 100644 config/environment.rb
create mode 100644 config/environments/development.rb
create mode 100644 config/environments/production.rb
create mode 100644 config/environments/test.rb
create mode 100644 config/initializers/application_controller_renderer.rb
create mode 100644 config/initializers/assets.rb
create mode 100644 config/initializers/backtrace_silencers.rb
create mode 100644 config/initializers/cookies_serializer.rb
create mode 100644 config/initializers/filter_parameter_logging.rb
create mode 100644 config/initializers/inflections.rb
create mode 100644 config/initializers/mime_types.rb
create mode 100644 config/initializers/wrap_parameters.rb
create mode 100644 config/locales/en.yml
create mode 100644 config/puma.rb
create mode 100644 config/routes.rb
create mode 100644 config/secrets.yml
create mode 100644 config/spring.rb
create mode 100644 db/seeds.rb
create mode 100644 lib/assets/.keep
create mode 100644 lib/tasks/.keep
create mode 100644 log/.keep
create mode 100644 package.json
create mode 100644 public/404.html
create mode 100644 public/422.html
create mode 100644 public/500.html
create mode 100644 public/apple-touch-icon-precomposed.png
create mode 100644 public/apple-touch-icon.png
create mode 100644 public/favicon.ico
create mode 100644 public/robots.txt
create mode 100644 test/application_system_test_case.rb
create mode 100644 test/controllers/.keep
create mode 100644 test/fixtures/.keep
create mode 100644 test/fixtures/files/.keep
create mode 100644 test/helpers/.keep
create mode 100644 test/integration/.keep
create mode 100644 test/mailers/.keep
create mode 100644 test/models/.keep
create mode 100644 test/system/.keep
create mode 100644 test/test_helper.rb
create mode 100644 tmp/.keep
create mode 100644 vendor/.keep
ec2-user:~/environment/myblog (master) $ git remote add origin git@bitbucket.org:メルアド/myblog.git
ec2-user:~/environment/myblog (master) $ git push -u origin master
Counting objects: 84, done.
Compressing objects: 100% (70/70), done.
Writing objects: 100% (84/84), 20.66 KiB | 1.21 MiB/s, done.
Total 84 (delta 2), reused 0 (delta 0)
To bitbucket.org:メルアド/myblog.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
bitbucketを確認したら反映されてました。
せっかくなのでブランチも作成して再度git pushまで。
ec2-user:~/environment/myblog (master) $ git checkout -b modify-README
Switched to a new branch 'modify-README'
ec2-user:~/environment/myblog (modify-README) $ git branch
master
* modify-README
ec2-user:~/environment/myblog (modify-README) $ git commit -a -m "Improve the README file"
[modify-README 1220e45] Improve the README file
1 file changed, 2 insertions(+)
ec2-user:~/environment/myblog (modify-README) $ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
ec2-user:~/environment/myblog (master) $ git merge modify-README
Updating cdc98bb..1220e45
Fast-forward
README.md | 2 ++
1 file changed, 2 insertions(+)
ec2-user:~/environment/myblog (master) $ git branch -d modify-README
Deleted branch modify-README (was 1220e45).
ec2-user:~/environment/myblog (master) $ git push
Counting objects: 3, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 307 bytes | 307.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To bitbucket.org:メルアド/myblog.git
cdc98bb..1220e45 master -> master
さて、せっかくなのでherokuもやる。
ただし、herokuは二個目もいけるんやろうか、まあいけないわけないか。
上書きとかもされないよね、URL違うし。きっと。
ec2-user:~/environment/myblog (master) $ git commit -a -m "Update Gemfile for Heroku"
[master 2359a4c] Update Gemfile for Heroku
1 file changed, 3 insertions(+)
ec2-user:~/environment/myblog (master) $ heroku --version
bash: heroku: command not found
ec2-user:~/environment/myblog (master) $ source <(curl -sL https://cdn.learnenough.com/heroku_install)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 27.4M 100 27.4M 0 0 57.0M 0 --:--:-- --:--:-- --:--:-- 57.0M
mv: cannot move ‘heroku’ to ‘/usr/local/heroku’: Directory not empty
ec2-user:~/environment/myblog (master) $ heroku create
Creating app... !
▸ You've reached the limit of 5 apps for unverified accounts. Delete some apps or add a credit card to verify your account.
ec2-user:~/environment/myblog (master) $ heroku apps
=== メルアド Apps
arcane-gorge-91888
infinite-gorge-77576
stark-reaches-53742
still-atoll-39193
warm-retreat-26779
どうやら、現状で5つのappを使っていてこれ以上は現状の申し込みじゃだめだよと言われた。
あきらめるかRailsチュートリアルを消すしかないないらしい。。。
しょうがない、開発環境のみで行こう。。。
ここで、プロゲートではやらなかった&チュートリアルではやってたところの穴埋めで
ec2-user:~/environment/myblog (master) $ rails db
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from posts;
rails seed
とかこの辺を積極的に試す。
ルーティングについて
続いて、Railsチュートリアルで最初、軽くながしたら後からえらい目にあった
ルーティングの書き方を復習。
resources raoutes
で
ec2-user:~/environment/myblog (master) $ rails routes
Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
これで確認ができることが素晴らしい。
このPrefix行をつかうことがプロゲート上がりが一番??だったところ。
さらに、謎を加速させたroot設定に関して。
トップページはそもそもrailsのデフォルトになっており、作成時は
posts GET /posts(.:format) posts#index
から、/postsで本来のトップページへのリンクとなっており、こちらを
/だけでトップにリンクできるようにするのがroot設定となる。たぶん。
root "posts#index"
こちらをルートに設定すると、、、
ec2-user:~/environment/myblog (master) $ rails routes
Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root GET / posts#index
一番下にrootが追加されてる。
posts#indexが一番上と一番下に二個できてるが下が優先されるのかなんなのかしらんけど
これで/でトップに。
しかし/postsでも同じページに。
続いてshowアクション、個別のページ。
トップからのリンクを用意してあげるのだが、、、↓
<% @posts.each do |post| %>
<li><%=link_to post.title,post_path(post.id) %></li>
<% end %>
link_toを使うときのリンク先に注目。
プロゲートではきちきちリンクURLをつかった気がするが、ドットインストールとチュートリアルではことなる。
リンク先はルーティングに書いているPrefixで表現できる。
今回のshowのPrefixはpostなのでpost_pathで表現できる。
※ちなみにPrefixがpostなのは、、、
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
となっている。
おそらく、GETやPATCHなどの動きに合わせてそれぞれを吐き出すみたいな仕様がRailsにはあるのではないかと思う。
あとは、:idという各ページにリンクさせてないといけないので(post.id)をつけてあげればよし。
ただ、ここは(post.id)ではなく、(post)だけでもRailsがいい感じに解釈してくれてOKらしい。
新規投稿エリア作成
続いて新規投稿に関して。
<%= form_for :post, url: posts_path do |f| %>
<p>
<%= f.text_field :title,placeholder:"タイトルをいれてください" %>
</p>
<p>
<%= f.text_area :body,placeholder:"本文をいれてください" %>
</p>
<p>
<%= f.submit %>
</p>
しれっとつかうform_for
form_for :postのpostはpostモデルにたいするものという意味らしいっす。
もうこれは覚えとくしかないっすね。
続いてcreateアクションについて。
def create
render plain: params[:post].inspect
end
ここもプロゲートではしらないコードがたくさん。
まず、render plainのplain。
これはそのまま文字情報をうけとることを示しているらしい。
で、params[:post]。
これ、こんなのあったかな。なぞ。
inspectは内容を文字列にして返すというメソッド、らしい。
よって、フォームのtitleとbodyにaaaといれて送信すると、、、
<ActionController::Parameters {"title"=>"aaa", "body"=>"aaa"} permitted: false>
きちんとおくられてることはわかる。
で、ほんとのコードは
class PostsController < ApplicationController
def index
@posts = Post.all.order(created_at: "desc")
end
def show
@post = Post.find(params[:id])
end
def new
end
def create
#render plain: params[:post].inspect
@post = Post.new(post_params)
@post.save
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:title, :body)
end
end
ここでprivateがでてくる。
まずprivate内の
params.require(:post).permit(:title, :body)について、
これはストロングパラメータ。
@post = Post.new(params[:post])だけだと、例外?とかをみとめちゃうから
きちんとするためにストロングパラメータにしないといけない、と。
きちんとするためのものが、
Post.new(params.require(:post).permit(:title, :body))
となる。
postキーにたいしてtitle、bodyの値があるハッシュとして送られてきてることを確認するもの。
で、このparams.require(:post).permit(:title, :body)部分をprivateに書き出して
post_paramsという名前のメソッドにして元のところの引数に入れる。
def create
#render plain: params[:post].inspect
@post = Post.new(post_params)
@post.save
redirect_to root_path
end
これで完成。
続いて、新規投稿のエラーメッセージ表示。
ここで、render plainの意味を理解する。
plainはそのまま文字でだせという意味だが、
def create
#render plain: params[:post].inspect
@post = Post.new(post_params)
if @post.save
redirect_to root_path
else
render plain:@post.errors.inspect
end
end
上記にすることで、createアクション、つまり新規投稿ボタンを押した際、遷移先のページにそのままコードから吐き出される記述を核という意味くさい。.inspectも含めて。
なので、上記のコードの状態で投稿ボタンを押すと、、、
#<ActiveModel::Errors:0x00007f85d41c7e68 @base=#<Post id: nil, title: "", body: "", created_at: nil, updated_at: nil>, @messages={:title=>["can't be blank", "文字数が不足しています。3文字以上記入してください。"], :body=>["can't be blank"]}, @details={:title=>[{:error=>:blank}, {:error=>:too_short, :count=>3}], :body=>[{:error=>:blank}]}>
という感じに吐き出される(日本語は別途設定したものでデフォルトではない)
これでエラーメッセージがでること&メッセージの編集がおわったので
もうplainや.inspectはいらない。コメントアウト。
render "new"にする。
def create
#render plain: params[:post].inspect
@post = Post.new(post_params)
if @post.save
redirect_to root_path
else
# render plain:@post.errors.inspect
render "new"
end
end
これで新規投稿はおしまい。
次は編集エリア。
ここからはその2にします。