- 投稿日:2020-02-04T23:21:55+09:00
herokuのデータのバックアップとローカルのデータベースへのリストア
- 投稿日:2020-02-04T22:35:37+09:00
[rubocop] インデントを揃えるgem【初学者おすすめgem】
概要
今回は効率よくインデントを揃えるgemの紹介をします。
プログラミングを学習してはや6ヶ月経ちました。
少しづつ転職も始め、ある企業様から私のgitをみてインデントがオカシイと非常にありがたいフィードバックを頂きました。
そこで第三者からみてコードの読みやすさの大切さに改めて気づきました。こんな人に読んでほしい!!
- 現在、プログラミングを独学またはプログラミングスクールで学び、転職しよう!って思っている方。
- インデントを効率よく揃える方法を知りたい!って思っている方。
- 綺麗なコードを書きたい!って方。
綺麗なコードを書く重要性
エンジニアとして働くにあたり、
他の人が読みやすいコードを意識する必要性があると思いました。理由
(1)プロダクトの共同開発
(2)万が一、担当から外る or 担当のメンバーが増えた際に、プロダクトのスムーズな引き継ぎ
(3)バクが起きた際に、可読性が高いと解決できるスピードが早まる※あくまで私が思い浮かんだ理由をあげました。もしかしたら他にも理由があるかも知れません。
以上の理由から、現場に入った後を考えると、他の人が読みやすいコードが重要性を増します。
今回は他の人が読みやすいコードにするための1つとして「インデントを揃える」をピックアップしました。rubocupとは?
RuboCopは、あなたのプロジェクトのrubyコードが「コーディング規約どおりに書かれているか」をチェックする静的コード解析ツールです。
その1つの機能として、インデントを揃えてくれます。使い方
導入
gemfile.group :development do gem 'rubocop', require: false #追記 endgemファイルのdevelopmentにgem 'rubocop', require: falseを追記します。
その後にターミナルで
$ rails bundle installを忘れずにします。インデントを揃えよう
ターミナルで
$ rubocop 修正したいファイル名をすると自動修正されます。
【例】$ rubocop sample.html.erb
これで修正されたと思います。
実行するとこのような感じで出ると思います。
出てきた内容を見ると、
[Corrected] Layout/IndentationWidth: Use 2 (not 4) spaces for indentation.
インデントを4つではなくて2つに修正しました。
こんな感じで実行後には、実行した内容を書いてくれてます。rubocopは「ある程度」まで修正できます。どういう風に修正したらいいのかわからない場合はスキップされるみたいです。
参考URL
RuboCopをRailsオプションやLintオプションで使ってみよう
公式ドキュメント
【初心者向け】Railsの品質を上げるRuboCopのインストールと使い方!最後に
まだまだ勉強不足なところがありますので、
アップデートできた知識は追加で記載していきます。もし、何か修正点とかございましたらコメント等
大変恐縮ですが、宜しくおねがいします。
- 投稿日:2020-02-04T21:21:48+09:00
rails チュートリアル2週目~ヘルスケアwebサービスを自分で作る医者の日記~
2章最後でつまづく
We're sorry, but something went wrong. If you are the application owner check the logs for more information.heroku run rails db:migrateするもだめ
ログ確認すると
2020-02-04T11:59:16.635000+00:00 heroku[router]: at=info method=GET path="/" host=hidden-ravine-49191.herokuapp.com request_id=309bfa62-5483-4e2d-84c9-2e306989f7d0 fwd="118.109.109.117" dyno=web.1 connect=0ms service=13ms status=500 bytes=1827 protocol=https
2020-02-04T11:59:16.622565+00:00 app[web.1]: I, [2020-02-04T11:59:16.622454 #4] INFO -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] Started GET "/" for 118.109.109.117 at 2020-02-04 11:59:16 +0000
2020-02-04T11:59:16.623211+00:00 app[web.1]: I, [2020-02-04T11:59:16.623135 #4] INFO -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] Processing by UsersController#index as HTML
2020-02-04T11:59:16.623867+00:00 app[web.1]: I, [2020-02-04T11:59:16.623790 #4] INFO -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] Rendering users/index.html.erb within layouts/application
2020-02-04T11:59:16.628739+00:00 app[web.1]: D, [2020-02-04T11:59:16.628649 #4] DEBUG -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] User Load (1.4ms) SELECT "users".* FROM "users"
2020-02-04T11:59:16.629812+00:00 app[web.1]: I, [2020-02-04T11:59:16.629733 #4] INFO -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] Rendered users/index.html.erb within layouts/application (5.8ms)
2020-02-04T11:59:16.630567+00:00 app[web.1]: I, [2020-02-04T11:59:16.630487 #4] INFO -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] Completed 500 Internal Server Error in 7ms (ActiveRecord: 1.4ms)
2020-02-04T11:59:16.631974+00:00 app[web.1]: F, [2020-02-04T11:59:16.631894 #4] FATAL -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0]
2020-02-04T11:59:16.632530+00:00 app[web.1]: F, [2020-02-04T11:59:16.632446 #4] FATAL -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] ActionView::Template::Error (PG::UndefinedTable: ERROR: relation "users" does not exist
2020-02-04T11:59:16.632535+00:00 app[web.1]: LINE 1: SELECT "users".* FROM "users"
2020-02-04T11:59:16.632538+00:00 app[web.1]: ^
2020-02-04T11:59:16.632541+00:00 app[web.1]: : SELECT "users".* FROM "users"):
2020-02-04T11:59:16.632798+00:00 app[web.1]: F, [2020-02-04T11:59:16.632721 #4] FATAL -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] 12: </thead>
2020-02-04T11:59:16.632801+00:00 app[web.1]: [309bfa62-5483-4e2d-84c9-2e306989f7d0] 13:
2020-02-04T11:59:16.632804+00:00 app[web.1]: [309bfa62-5483-4e2d-84c9-2e306989f7d0] 14: <tbody>
2020-02-04T11:59:16.632807+00:00 app[web.1]: [309bfa62-5483-4e2d-84c9-2e306989f7d0] 15: <% @users.each do |user| %>
2020-02-04T11:59:16.632810+00:00 app[web.1]: [309bfa62-5483-4e2d-84c9-2e306989f7d0] 16: <tr>
2020-02-04T11:59:16.632812+00:00 app[web.1]: [309bfa62-5483-4e2d-84c9-2e306989f7d0] 17: <td><%= user.name %></td>
2020-02-04T11:59:16.632814+00:00 app[web.1]: [309bfa62-5483-4e2d-84c9-2e306989f7d0] 18: <td><%= user.email %></td>
2020-02-04T11:59:16.632921+00:00 app[web.1]: F, [2020-02-04T11:59:16.632847 #4] FATAL -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0]
2020-02-04T11:59:16.633036+00:00 app[web.1]: F, [2020-02-04T11:59:16.632965 #4] FATAL -- : [309bfa62-5483-4e2d-84c9-2e306989f7d0] app/views/users/index.html.erb:15:in `_app_views_users_index_html_erb__912488948079837038_47098446139840'
^C
よくわからない。とりあえず3章へいく
- 投稿日:2020-02-04T20:28:30+09:00
if current_user.admin? && !current_user?(user)で「!」が必要な理由
事象
railsチュートリアル「10.4.2 destroyアクション」において、
「現在のユーザーが管理者のときに限り」という条件を作るためにチュートリアルでは、下記のように記載されていました。app/views/users/_user.html.erb<% if current_user.admin? && !current_user?(user) %>2つの条件が成り立つ場合のif文になります。
右の条件において先頭に「!」が必要になる理由がわからなかったので記事にしました。
具体的には、現在のユーザーを「!」で否定すると条件が成り立たないのではと疑問に思っていました。※左の条件は現在ログインしているユーザーが管理者権限を持つか判定しています。
!の意味
!はnot演算子です。
式の値が真である時偽を、偽である時真を返します。
!true=>false
!false=>true
!current_user?(user)が何を表すか
current_user?の判定を「!」で逆転しています。
ここでは、
current_user?がtrueならfalseで返し、
current_user?がfalseならtrueで返します。忘れがちなeach文の存在
チュートリアルでややこしいことをやっているといま自分が何をやっているかわからなくなってしまうことが1周目だとちょくちょくありました。それゆえの失念だと思いますが、
そもそも、表題の条件文はeach文の中にあります。
下記がrender元のeach文ですapp/views/users/index.html.erb<ul class="users"> #省略型のeach文を表しています <%= render @users %> </ul>下記がrender先になります。
app/views/users/_user.html.erb<li> <%= gravatar_for user, size: 50 %> <%= link_to user.name, user %> <% if current_user.admin? && !current_user?(user) %> | <%= link_to "delete", user, method: :delete, data: { confirm: "You sure?" } %> <% end %> </li>このためuserの部分にユーザーの全レコードがそれぞれ入れられていく処理になります。
するとif分の結果として下記の4通りあるはずです。①真&&真(=管理者 かつ userがcurrent_user)
②真&&偽(=管理者 かつ userがcurrent_userではない)
③偽&&真(=非管理者 かつ userがcurrent_user)
④偽&&偽(=非管理者 かつ userがcurrent_userではない)そして
!current_user?(user)
この条件はeach分によって割り当てられたuserが現在ログイン中のcurrent_user(=ここでは管理者)と同じかを判定しています。
管理者で無い限り!falseとなり、結果trueになります。初見ではちょっとわかりづらい部分かと思います。
成り立つのは②の「管理者 かつ userがcurrent_userではない」時のみになります。まとめ
if current_user.admin? && !current_user?(user)
上記の文は管理者かつeach文によって割り当てられたuserが管理者(current_user)で無い限り成り立つことになります。よって、管理者がユーザー一覧ページを開くと管理者以外のユーザーに対して削除ボタンを追加できるようになっています。
つまり管理者が自分自身を消せないようにもなっています。参考
・https://docs.ruby-lang.org/ja/latest/doc/symref.html
・https://teratail.com/questions/198416
- 投稿日:2020-02-04T19:56:14+09:00
【jQuery】リロードしないとプレビュー表示できない→turbolinksが原因
写真投稿アプリを作成中に、jQueryを用いてプレビュー表示機能を実装しようとした所、うまくプレビュー機能が機能せず、リロードを行うとプレビュー表示が成功するという問題に直面しました。
調べた所、初心者に多いミスらしく、私自身もJavaScriptにおいてturbolinksの概念が無かったため、解決にかなり時間を要しました。
ネット上でも同じような悩みを抱えている方が多かったため、参考になればと思い手順をまとめました。環境
ruby 2.5.1
rails 5.2.4やりたかった事
写真投稿フォーム
↓
画像を選択
↓
選択した画像がプレビュー表示される発生した問題
写真投稿フォーム
↓
画像を選択
↓
$\color{red}{\rm 選択した画像がプレビュー表示されない}$
↓
リロード
↓
画像を選択
↓
選択した画像がプレビュー表示される問題のコード
jquery$(function(){ fileField = $('#file') #選択された画像を取得し表示 fileField.on('change', fileField, function(e) { var file = e.target.files[0] var reader = new FileReader(), $preview = $("#img-field"); reader.onload = (function(file) { return function(e) { $preview.empty(); $preview.append($('<img>').attr({ src: e.target.result, width: "100%", class: "preview", title: file.name })); }; })(file); reader.readAsDataURL(file); }); });解決方法
jquery$(document).on('turbolinks:load', function() { #上記のコードをここに挟む });turbolinksによりJSが機能しない時があるとの事。
上記のように囲むことで、この問題は解決するようです。turbolinksとは
turbolinksとは、一言で言うとWebアプリケーションをすばやく表示させることができるgemのこと。
rails4以降標準で用意されている。初心者の方や、慣れている方でも忘れることが多いみたいなので、
JSが変だと思ったら、turbolinksを疑ってみましょう。
- 投稿日:2020-02-04T17:36:02+09:00
【Rails】Action Mailerのメール送信に失敗する
症状
Action Mailerを利用したメール送信処理で、以下のエラーを吐いてしまう。
なお以前は正常に送信することができていた。
Net::SMTPAuthenticationError (530 Authentication required):
ArgumentError (SMTP To address may not be blank: []):原因
環境変数を正常に読み込めていなかった。
SMTP認証情報やお問い合わせ宛先メールアドレスを環境変数に入れていたため、それらの情報を利用することができず、送信に失敗した。対処
1.アプリケーションサーバー停止
pumactl stop2.アプリケーションサーバー起動
rails s根本原因は?
不明。
EC2のインスタンスを止めたり、立ち上げたりしていたので、それが契機っぽいが。。
- 投稿日:2020-02-04T14:36:58+09:00
config/initializeにカスタムバリデータを定義する
電話番号にバリデーションを使用する
telephone_numberというgemを使用してカスタムバリデーションを定義する。
まずはgemを定義
gem 'telephone_number'そしてbundle install!
$ bundleconfig/initializeに下記のように定義
config/initialize.rbmodule ActiveModel module Validations class TelValidator < EachValidator def validate_each(record, attribute, value) return if value.blank? record.errors.add attribute, :invalid unless TelephoneNumber.valid?(value, :jp) end module HelperMethods def validates_tel_of(*attr_names) validates_with TelValidator, _merge_attributes(attr_names) end end end end endそしてあとは個別のモデルで下記のようにすれば電話番号のバリデーションがかかってくれる。
hoge.rbvalidates :tel, tel: true参考記事
- 投稿日:2020-02-04T14:36:58+09:00
config/initializersにカスタムバリデータを定義する
電話番号にバリデーションを使用する
telephone_numberというgemを使用してカスタムバリデーションを定義する。
まずはgemを定義
gem 'telephone_number'そしてbundle install!
$ bundleconfig/initializeに下記のように定義
config/initializers/tel_validator.rbmodule ActiveModel module Validations class TelValidator < EachValidator def validate_each(record, attribute, value) return if value.blank? record.errors.add attribute, :invalid unless TelephoneNumber.valid?(value, :jp) end module HelperMethods def validates_tel_of(*attr_names) validates_with TelValidator, _merge_attributes(attr_names) end end end end endそしてあとは個別のモデルで下記のようにすれば電話番号のバリデーションがかかってくれる。
hoge.rbvalidates :tel, tel: true参考記事
- 投稿日:2020-02-04T12:04:56+09:00
コード書いたことないPdMやPOに捧ぐ、Rails on Dockerハンズオン vol.2 -Hello, Rails on Docker-
この記事はなにか?
この記事は私が社内のプログラミング未経験者、ビギナー向けに開催しているRuby on Rails on Dockerハンズオンの内容をまとめたものです。ていうかこの記事を基にそのままハンズオンします。ハンズオンは
1回の内容は喋りながらやると大体40~50分くらいになっています。お昼休みに有志でやっているからです。
現在進行形なので週1ペースで記事投稿していけるように頑張ります。
ビギナーの方のお役にたったり、同じように有志のハンズオンをしようとしている人の参考になれば幸いです。
$,#,>について
$: ローカルでコマンドを実行するときは、頭に$をつけています。
#: コンテナの中でコマンドを実行するときは、頭に#をつけています。
>: Rails console内でコマンド(Rubyプログラム)を実行するときは、頭に>をつけています。
はじめに
第二回目の今回は、Ruby on RailsをDockerコンテナで起動させるHello worldをやっていきます。
今日のゴール
- Ruby on Rails on Docker で Hello world する
では早速、Ruby on Rails on Docker で Hello world していきましょう!
Hello, Ruby on Rails on Docker
今回は↓の図のように、Docker 上に Rails アプリケーション用のコンテナと PostgreSQL (database) 用のコンテナを作っていきます。
まず、作業用のディレクトリを作っておきましょう。$ mkdir Handson $ cd Handson今後、この
Handsonディレクトリをホームディレクトリとして話を進めますので、特に指定がない場合、Handsonディレクトリでコマンドを叩いたり、Handsonディレクトリから見た相対パスでファイルを編集していると思ってください。では早速、Ruby on Rails on Docker な環境を構築するために以下の4つのファイルを作成していきます。
Dockerfile: Rails アプリ用の Docker image の元となる設計図Gemfile: Rails アプリに必要なgemを記載するファイルGemfile.lock:Gemfileによってインストールされたgemのバージョン情報などを管理するファイルdocker-compose.yml: 今回のアプリをコンテナ起動させるための Dcoker Compose ファイルDockerfile
DockerfileFROM ruby:2.7.0-alpine3.11 ENV HOME="/app" ENV LANG=C.UTF-8 ENV TZ=Asia/Tokyo WORKDIR $HOME RUN apk update && \ apk upgrade && \ apk add --no-cache \ gcc \ g++ \ libc-dev \ libxml2-dev \ linux-headers \ make \ nodejs \ postgresql \ postgresql-dev \ tzdata \ yarn && \ apk add --virtual build-packs --no-cache \ build-base \ curl-dev COPY Gemfile $HOME COPY Gemfile.lock $HOME RUN bundle install && \ apk del build-packs COPY . $HOME EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"]Dockerfile は初めて見る人にとっては「なんだこれ?」なものな気がしますが、読んでみると意外とシンプルです。
頭に大文字で書かれているのが命令と呼ばれるものでコマンドみたいなものです。
今回の Dockerfile では以下の命令を利用しています。
FROM: ベースイメージを定義する命令です。ruby イメージを指定しているので、元々 Ruby を使用できるイメージの上に Rails を動かす環境を作っていきます。タグの2.7.0-alpine3.11は2020.02.02時点で Ruby の最新バージョンを軽量ディストリビューションとしておなじみの alpine linux のこれまた最新バージョン3.11上で動かしているものを選んでいます。ENV: 環境変数を定義する命令です。WORKDIR: 作業ディレクトリを定義する命令です。ベースイメージ内に該当のディレクトリがない場合は、そのディレクトリを作成することもしてくれます。COPY: ホストのファイルやディレクトリをイメージ内にコピーする命令です。RUN: コマンドを実行する命令です。EXPOSE: コンテナがリッスンするポートを宣言する命令です。 Rails ではデフォルトで 3000 番ポートを使用するので 3000 を指定してあげています。CMD: ソフトウェアを実行するためのコマンドを定義する命令です。コンテナが起動する時に実行されるコマンドといった方がイメージ湧きやすいかもしれません。少し特別な書き方(["xxx", "xxx"]みたいな)をしますが、Rails アプリケーションを起動させるコマンドはrails server -b 0.0.0.0でして、それをCMDの記法で書いています。あらかた命令と1行1行の内容について述べてしまいましたが、取りこぼしているところをキャッチアップ。
RUN宣言でapk ~と色々書いている9行目からの部分がありますが、apk addは Alpine linux でパッケージをインストールするコマンドです。
apk updateでパッケージリポジトリの最新のインデックス(インストールできる最新バージョンは何か)を取得してきて、apk upgradeですでにインストールしているパッケージで最新版にアップデートできるものをアップデートします。その後、apk addで Rails を起動するのに必要なパッケージをインストールしていきます。--no-cacheオプションはキャッシュを残さないようにするためのオプションです。不要なキャッシュを残さないことでコンテナ自体を軽量に保つことができます。(コンテナは軽量に保っておいた方がダウンロードに時間がかからなかったり、ホストのボリュームを圧迫しないのでよいとされています。)--virtualオプションはそのインストールしたパッケージ達を一つのグループとして名前づけしています。今回の例だとbuild-packsという名前をつけています。ここでインストールしたパッケージは Rails をビルドする上では必要なのですが起動させるためには不要なのであとでapk delで削除するために名前づけしています。その後、
COPY命令でGemfile、Gemfile.lockをイメージ内にコピーして、bundle installを実行してます。bundle installはGemfileの内容に沿ってgemをインストールするコマンドです。Rails 自体もgemでインストールできるのでGemfileにrailsを記入しておけばこのbundle installの際にインストールされます。Gemfile.lockはすでにインストール済のgemのバージョンなどを管理して無闇にバージョンアップさせないようにしてくれます。最後に
COPY . $HOMEでローカルホストのファイルを一式イメージ内にコピーすることで Rails アプリケーションを起動させられる Docker image を作ることができます。Gemfile
Gemfilesource 'https://rubygems.org' gem 'rails', '~>6'Gemfileはかなりシンプルで、インストールする
gemのソースとrailsgem をインストールすることを定義しています。Rails は2020.02.02時点で最新バージョンが 6.0.2 なのでまぁメジャーバージョンとして 6 のものをインストールしてくださいというような指定の仕方をしています。
Rails アプリケーションでは最初rails newコマンドでアプリに必要なgemやファイルをインストール・生成するため、初期ではこれほどシンプルなGemfileがあるだけで構わないのです。
Gemfileでバージョンを指定する表現方法はいくつかあります。gemはGitHubなどで公開されていることが多くて大体 README でこう Gemfile に記載してくれと書かれていることが多いのであんまり気にすることはないかもしれませんが一応紹介。
gem 'rails', '6.0.0': 絶対 6.0.0 をインストール(バージョンを定義)gem 'rails', >= 6.0.0': 6.0.0 より最新のものをインストール(最低バージョンを定義)gem 'rails', >= 6.0.0', < 6.0.2: 6.0.0 以上 6.0.2 未満のバージョンをインストール(バージョンの範囲を定義)gem 'rails', '~> 6.0.0': 6.0.X のバージョンをインストール(マイナーバージョンを定義)Gemfile.lock
Gemfile.lockは最初にbundle installされるときに書き込まれるので、最初は空ファイルで問題ありません。$ touch Gemfile.lock
touchコマンドはファイルの更新日時を現在時刻に更新するためのコマンドですが、ファイルが存在しない場合は空ファイルを生成してくれるのでGemfile.lockを生成するために使いました。docker-compose.yml
docker-compose.ymlversion: '3' services: db: image: postgres:12.1-alpine environment: - TZ=Asia/Tokyo volumes: - ./tmp/db:/var/lib/postgresql/data web: build: . volumes: - .:/app ports: - 3000:3000 depends_on: - dbまず、サービスとして
dbとwebの二つがあることがわかるかと思います。dbは文字通りデータベース用のコンテナ(サービス)、webは Rails アプリケーションを動作させるコンテナ(サービス)です。dbコンテナではimageにpostgres:12.1-alpineを指定しています。
docker-compose.ymlについては前回もお話したので、前回お話していない項目を中心にお話します。
environment: コンテナを起動する時に環境変数としてセットする。この場合、TZ(タイムゾーン)を東京にしてる。volumes: コンテナからホストのディレクトリをマウントしている。左がホストのパス、右がコンテナ内のパス。ホストのパスはこのdocker-compose.ymlの場所からの相対パスで書いてます。こう書くことで簡単にいえば、ホストのパスとコンテナのパスを同期しているイメージになり、ホストでファイルを編集すればコンテナ内にも反映され、コンテナ内でファイルが編集されればホストのファイルにも反映されるという関係を気づけます。コンテナはステートレスなので一度コンテナを削除して新しくコンテナを起動させた場合、最初のコンテナ(削除したコンテナ)内で変更されたデータは全てなかったことになってしまうのですが、ホストのディレクトリに同期しておくことで次に起動するコンテナもそのディレクトリをマウントするのでデータが永続化されるようになります。build:build: .でdocker-compose.ymlと同じディレクトリのDockerfileをbuildしたイメージを使ってコンテナを起動するようになります。depends_on: コンテナの依存関係を定義します。今回の場合『webはdbに依存している』と定義していることになりますが、これは次の2つが実現されます。
docker-compose upした時に、dbコンテナが起動してからwebコンテナを起動するdocker-compose up webでwebコンテナを起動させようとした場合、dbコンテナも起動させるRails アプリケーションを新規作成
まずは
rails newコマンドで新規に Rails アプリを作成します。$ docker-compose run --rm --no-deps web rails new . -fGTd postgresql ... Webpacker successfully installed ??いろいろな要素のあるコマンドですね。ちょっと順を追って説明します。
まずこのコマンドの大枠はdocker-compose run [options] <service name> <command>です。今回の例では、
- [options]:
--rm --no-deps- <service name>:
web- <command>:
rails new . -fGTd postgresqlとなっています。
docker-compose runはdocker-compose.ymlの定義にそって対象のコンテナを立ち上げてその中でコマンドを実行し、実行後にコンテナを停止するコマンドです。つまり、webコンテナを立ち上げてrails new . -fGTd postgresqlをwebコンテナ内で実行してくれます。
--rmオプションはコマンド実行後にコンテナを停止した後に削除までしてくれるオプションです。基本停止したコンテナは不要だと思うのでこのオプションをつけるのがよきかと思います。
--no-depsオプションはdocker-compose.ymlでdepends_onが定義されていたとしてもそれを無視してdocker-compose runを実行することができます。次に
webコンテナで実行されるrails new . -fGTd postgresqlを見ていきましょう。
まずrails newは Rails アプリケーションを新規作成するためのコマンドです。.はアプリケーションを作成する場所を指していてカレントディレクトリ(コマンドが実行されたディレクトリ)を示しています。-fGTdはオプションなので一つずつ紐解きます。
-f: ファイルの上書きを強制する。Gemfileなどに上書きが走りますがいちいち Yes or No を聞かれないようにするためにつけています。-G: Gitの初期設定をスキップします。Rails 6 からなんかこのオプションをつけないとまともにrails newできなかったのでつけてます。-T:minitestという Rails でデフォルトでインストールされるテストフレームワークのインストールをスキップします。僕はRSpecというテストフレームワークをよく使っているのでこのオプションをつけて無駄にminitestがインストールされないようにしています。-d:-d <database name>で利用するデータベースを指定します。今回はpostgresqlを指定。Rails アプリケーションの新規作成ができたら一度イメージをビルドしておきましょう。
$ docker-compose build ... Successfully tagged handson_web:latest
docker-compose buildコマンドはdocker-compose.ymlでDockerfileからのビルドが必要なサービスのイメージビルドをすべて実行してくれます。今回はdbは DockerHub のイメージを使っているのでwebのみがビルドが必要なサービスとしてビルドされます。DBの接続設定
ビルドが終わったら、Rails アプリケーションの DB 接続設定をコーディングしていきます。 DB の接続設定は
config/database.ymlに記載します。 Rails では設定系のファイルはconfigディレクトリに格納されています。config/database.yml... default: &default adapter: postgresql encoding: unicode host: db username: postgres password: pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> ...
host、username、passwordがデフォルトから新たに追加した項目です。
hostはDBのホスト名です。今 Rails アプリが稼働しているwebコンテナはdocker-compose.ymlが作る Docker ネットワークの中にいます。この中ではサービス名で名前解決してコンテナが相互に接続することができます。つまりhostとしてdbを設定することでdocker-compose.ymlでdbのサービス名で定義されたコンテナに接続できるようになるのです。
usernameとpasswordは何の値なのでしょうか?これはdbコンテナのイメージで指定したpostgresのデフォルト値です。passwordは同じホストからのアクセスであれば省略が可能になっています。postgresイメージのusernameとpasswordはそれぞれPOSTGRES_USERとPOSTGRES_PASSWORDの環境変数で定義することもできます。データベースの設定はここまでです。このデフォルトの設定値が開発環境(
development)、テスト環境(test)の設定値として反映されるようになっています。データベースを作成する
データベースの接続設定を定義したので、データベースを実際に作成していきます。
Rails ではデフォルトで本番環境(production)、開発環境(development)、テスト環境(test)の3つの環境(environment)が用意されています。特別に環境を指定しない場合、開発環境で挙動するようになっています。
データベースの作成はrails db:createコマンドを使いますが、このコマンドは開発環境とテスト環境用にデータベースを作成してくれます。本番環境用のデータベースを作成する場合は、RAILS_ENV=productionをオプションとしてつけます。
今回はまず開発環境向けにデータベースの作成を行いたいので、以下のコマンドを実行します。$ docker-compose run --rm rails db:createHello Ruby on Rails on Docker!!
ここまでで Hello world に必要な作業は全て完了しました。
コンテナを立ち上げて Hello world ページが表示されることを確認しましょう。$ docker-compose up -dRails アプリは少し起動に時間がかかります。すぐに
http://localhost:3000にアクセスしてもまだアプリケーションが起動していないこともありますので、その場合はdocker-compose logsコマンドを使ってアプリケーションの起動状態を確認してみましょう。$ docker-compose logs -f
-fオプションはログの変化をリアルタイムでコンソールに表示するためのオプションです。Rails アプリが起動した場合web_1 | Use Ctrl+C to stopというログが表示されます。この表示を確認したら
Ctrl+Cでdocker-compose logsから抜け出しましょう。では、
http://localhost:3000にアクセスしてみましょう!
このようなページが表示されたでしょうか?このページが Rails アプリケーションの第一歩、つまり Hello world です。おめでとうございます!これでもう『Rails は Hello world までならやったことあります』と自慢することができます!ここまでできたら後片付けをしておきましょう。
このままではコンテナが起動しっぱなしになってしまうので、最後にコンテナを停止させておきます。$ docker-compose downこれでコンテナを停止させたので、
http://localhost:3000にアクセスしても先ほどのページは表示されなくなっていることでしょう。まとめ
今回は、
Dockerfileやdocker-compose.ymlなどのファイルを作成し、Rails アプリケーションを稼働させられる Docker イメージ、Docker コンテナを作成してみました。
さらに、Rails アプリを新規作成して Hello world に成功しました!
まだまだアプリケーション開発のほんの入り口ですが、Docker を使って Web アプリを起動させることができただけでもかなり感動があると思いますし、ここまでさほど大変ではないことも感じてもらえたかなと思います。これこそが Rails や Docker の偉大なところですね。次回は、
scaffoldという Rails の便利機能を使って、サンプル Web アプリケーションを作ってみようと思います。このscaffoldで作成できるアプリケーションが Rails の基本的なアプリケーションの形になりまして、その中には Rails アプリケーションを語る上では避けられないRESTfulやMVCの要素が詰まっていますので、その辺りも合わせて学んでいけるようにしようと思います。では、次回も乞うご期待!ここまでお読みいただきありがとうございました!
Reference
P.S. 間違っているところ、抜けているところ、説明の仕方を変えるとよりわかりやすくなるところなどありましたら、優しくアドバイスいただけると助かります。
- 投稿日:2020-02-04T12:04:56+09:00
コード書いたことないPdMやPOに捧ぐ、Ruby on Rails on Dockerハンズオン vol.2 -Hello, Ruby on Rails on Docker-
この記事はなにか?
この記事は私が社内のプログラミング未経験者、ビギナー向けに開催しているRuby on Rails on Dockerハンズオンの内容をまとめたものです。ていうかこの記事を基にそのままハンズオンします。ハンズオンは
1回の内容は喋りながらやると大体40~50分くらいになっています。お昼休みに有志でやっているからです。
現在進行形なので週1ペースで記事投稿していけるように頑張ります。
ビギナーの方のお役にたったり、同じように有志のハンズオンをしようとしている人の参考になれば幸いです。
他のハンズオンへのリンク
- Ruby on Rails on Dockerハンズオン vol.1 -Introduction-
$,#,>について
$: ローカルでコマンドを実行するときは、頭に$をつけています。
#: コンテナの中でコマンドを実行するときは、頭に#をつけています。
>: Rails console内でコマンド(Rubyプログラム)を実行するときは、頭に>をつけています。
はじめに
第二回目の今回は、Ruby on RailsをDockerコンテナで起動させるHello worldをやっていきます。
今日のゴール
- Ruby on Rails on Docker で Hello world する
では早速、Ruby on Rails on Docker で Hello world していきましょう!
Hello, Ruby on Rails on Docker
今回は↓の図のように、Docker 上に Rails アプリケーション用のコンテナと PostgreSQL (database) 用のコンテナを作っていきます。
まず、作業用のディレクトリを作っておきましょう。$ mkdir Handson $ cd Handson今後、この
Handsonディレクトリをホームディレクトリとして話を進めますので、特に指定がない場合、Handsonディレクトリでコマンドを叩いたり、Handsonディレクトリから見た相対パスでファイルを編集していると思ってください。では早速、Ruby on Rails on Docker な環境を構築するために以下の4つのファイルを作成していきます。
Dockerfile: Rails アプリ用の Docker image の元となる設計図Gemfile: Rails アプリに必要なgemを記載するファイルGemfile.lock:Gemfileによってインストールされたgemのバージョン情報などを管理するファイルdocker-compose.yml: 今回のアプリをコンテナ起動させるための Dcoker Compose ファイルDockerfile
DockerfileFROM ruby:2.7.0-alpine3.11 ENV HOME="/app" ENV LANG=C.UTF-8 ENV TZ=Asia/Tokyo WORKDIR $HOME RUN apk update && \ apk upgrade && \ apk add --no-cache \ gcc \ g++ \ libc-dev \ libxml2-dev \ linux-headers \ make \ nodejs \ postgresql \ postgresql-dev \ tzdata \ yarn && \ apk add --virtual build-packs --no-cache \ build-base \ curl-dev COPY Gemfile $HOME COPY Gemfile.lock $HOME RUN bundle install && \ apk del build-packs COPY . $HOME EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"]Dockerfile は初めて見る人にとっては「なんだこれ?」なものな気がしますが、読んでみると意外とシンプルです。
頭に大文字で書かれているのが命令と呼ばれるものでコマンドみたいなものです。
今回の Dockerfile では以下の命令を利用しています。
FROM: ベースイメージを定義する命令です。ruby イメージを指定しているので、元々 Ruby を使用できるイメージの上に Rails を動かす環境を作っていきます。タグの2.7.0-alpine3.11は2020.02.02時点で Ruby の最新バージョンを軽量ディストリビューションとしておなじみの alpine linux のこれまた最新バージョン3.11上で動かしているものを選んでいます。ENV: 環境変数を定義する命令です。WORKDIR: 作業ディレクトリを定義する命令です。ベースイメージ内に該当のディレクトリがない場合は、そのディレクトリを作成することもしてくれます。COPY: ホストのファイルやディレクトリをイメージ内にコピーする命令です。RUN: コマンドを実行する命令です。EXPOSE: コンテナがリッスンするポートを宣言する命令です。 Rails ではデフォルトで 3000 番ポートを使用するので 3000 を指定してあげています。CMD: ソフトウェアを実行するためのコマンドを定義する命令です。コンテナが起動する時に実行されるコマンドといった方がイメージ湧きやすいかもしれません。少し特別な書き方(["xxx", "xxx"]みたいな)をしますが、Rails アプリケーションを起動させるコマンドはrails server -b 0.0.0.0でして、それをCMDの記法で書いています。あらかた命令と1行1行の内容について述べてしまいましたが、取りこぼしているところをキャッチアップ。
RUN宣言でapk ~と色々書いている9行目からの部分がありますが、apk addは Alpine linux でパッケージをインストールするコマンドです。
apk updateでパッケージリポジトリの最新のインデックス(インストールできる最新バージョンは何か)を取得してきて、apk upgradeですでにインストールしているパッケージで最新版にアップデートできるものをアップデートします。その後、apk addで Rails を起動するのに必要なパッケージをインストールしていきます。--no-cacheオプションはキャッシュを残さないようにするためのオプションです。不要なキャッシュを残さないことでコンテナ自体を軽量に保つことができます。(コンテナは軽量に保っておいた方がダウンロードに時間がかからなかったり、ホストのボリュームを圧迫しないのでよいとされています。)--virtualオプションはそのインストールしたパッケージ達を一つのグループとして名前づけしています。今回の例だとbuild-packsという名前をつけています。ここでインストールしたパッケージは Rails をビルドする上では必要なのですが起動させるためには不要なのであとでapk delで削除するために名前づけしています。その後、
COPY命令でGemfile、Gemfile.lockをイメージ内にコピーして、bundle installを実行してます。bundle installはGemfileの内容に沿ってgemをインストールするコマンドです。Rails 自体もgemでインストールできるのでGemfileにrailsを記入しておけばこのbundle installの際にインストールされます。Gemfile.lockはすでにインストール済のgemのバージョンなどを管理して無闇にバージョンアップさせないようにしてくれます。最後に
COPY . $HOMEでローカルホストのファイルを一式イメージ内にコピーすることで Rails アプリケーションを起動させられる Docker image を作ることができます。Gemfile
Gemfilesource 'https://rubygems.org' gem 'rails', '~>6'Gemfileはかなりシンプルで、インストールする
gemのソースとrailsgem をインストールすることを定義しています。Rails は2020.02.02時点で最新バージョンが 6.0.2 なのでまぁメジャーバージョンとして 6 のものをインストールしてくださいというような指定の仕方をしています。
Rails アプリケーションでは最初rails newコマンドでアプリに必要なgemやファイルをインストール・生成するため、初期ではこれほどシンプルなGemfileがあるだけで構わないのです。
Gemfileでバージョンを指定する表現方法はいくつかあります。gemはGitHubなどで公開されていることが多くて大体 README でこう Gemfile に記載してくれと書かれていることが多いのであんまり気にすることはないかもしれませんが一応紹介。
gem 'rails', '6.0.0': 絶対 6.0.0 をインストール(バージョンを定義)gem 'rails', >= 6.0.0': 6.0.0 より最新のものをインストール(最低バージョンを定義)gem 'rails', >= 6.0.0', < 6.0.2: 6.0.0 以上 6.0.2 未満のバージョンをインストール(バージョンの範囲を定義)gem 'rails', '~> 6.0.0': 6.0.X のバージョンをインストール(マイナーバージョンを定義)Gemfile.lock
Gemfile.lockは最初にbundle installされるときに書き込まれるので、最初は空ファイルで問題ありません。$ touch Gemfile.lock
touchコマンドはファイルの更新日時を現在時刻に更新するためのコマンドですが、ファイルが存在しない場合は空ファイルを生成してくれるのでGemfile.lockを生成するために使いました。docker-compose.yml
docker-compose.ymlversion: '3' services: db: image: postgres:12.1-alpine environment: - TZ=Asia/Tokyo volumes: - ./tmp/db:/var/lib/postgresql/data web: build: . volumes: - .:/app ports: - 3000:3000 depends_on: - dbまず、サービスとして
dbとwebの二つがあることがわかるかと思います。dbは文字通りデータベース用のコンテナ(サービス)、webは Rails アプリケーションを動作させるコンテナ(サービス)です。dbコンテナではimageにpostgres:12.1-alpineを指定しています。
docker-compose.ymlについては前回もお話したので、前回お話していない項目を中心にお話します。
environment: コンテナを起動する時に環境変数としてセットする。この場合、TZ(タイムゾーン)を東京にしてる。volumes: コンテナからホストのディレクトリをマウントしている。左がホストのパス、右がコンテナ内のパス。ホストのパスはこのdocker-compose.ymlの場所からの相対パスで書いてます。こう書くことで簡単にいえば、ホストのパスとコンテナのパスを同期しているイメージになり、ホストでファイルを編集すればコンテナ内にも反映され、コンテナ内でファイルが編集されればホストのファイルにも反映されるという関係を気づけます。コンテナはステートレスなので一度コンテナを削除して新しくコンテナを起動させた場合、最初のコンテナ(削除したコンテナ)内で変更されたデータは全てなかったことになってしまうのですが、ホストのディレクトリに同期しておくことで次に起動するコンテナもそのディレクトリをマウントするのでデータが永続化されるようになります。build:build: .でdocker-compose.ymlと同じディレクトリのDockerfileをbuildしたイメージを使ってコンテナを起動するようになります。depends_on: コンテナの依存関係を定義します。今回の場合『webはdbに依存している』と定義していることになりますが、これは次の2つが実現されます。
docker-compose upした時に、dbコンテナが起動してからwebコンテナを起動するdocker-compose up webでwebコンテナを起動させようとした場合、dbコンテナも起動させるRails アプリケーションを新規作成
まずは
rails newコマンドで新規に Rails アプリを作成します。$ docker-compose run --rm --no-deps web rails new . -fGTd postgresql ... Webpacker successfully installed ??いろいろな要素のあるコマンドですね。ちょっと順を追って説明します。
まずこのコマンドの大枠はdocker-compose run [options] <service name> <command>です。今回の例では、
- [options]:
--rm --no-deps- <service name>:
web- <command>:
rails new . -fGTd postgresqlとなっています。
docker-compose runはdocker-compose.ymlの定義にそって対象のコンテナを立ち上げてその中でコマンドを実行し、実行後にコンテナを停止するコマンドです。つまり、webコンテナを立ち上げてrails new . -fGTd postgresqlをwebコンテナ内で実行してくれます。
--rmオプションはコマンド実行後にコンテナを停止した後に削除までしてくれるオプションです。基本停止したコンテナは不要だと思うのでこのオプションをつけるのがよきかと思います。
--no-depsオプションはdocker-compose.ymlでdepends_onが定義されていたとしてもそれを無視してdocker-compose runを実行することができます。次に
webコンテナで実行されるrails new . -fGTd postgresqlを見ていきましょう。
まずrails newは Rails アプリケーションを新規作成するためのコマンドです。.はアプリケーションを作成する場所を指していてカレントディレクトリ(コマンドが実行されたディレクトリ)を示しています。-fGTdはオプションなので一つずつ紐解きます。
-f: ファイルの上書きを強制する。Gemfileなどに上書きが走りますがいちいち Yes or No を聞かれないようにするためにつけています。-G: Gitの初期設定をスキップします。Rails 6 からなんかこのオプションをつけないとまともにrails newできなかったのでつけてます。-T:minitestという Rails でデフォルトでインストールされるテストフレームワークのインストールをスキップします。僕はRSpecというテストフレームワークをよく使っているのでこのオプションをつけて無駄にminitestがインストールされないようにしています。-d:-d <database name>で利用するデータベースを指定します。今回はpostgresqlを指定。Rails アプリケーションの新規作成ができたら一度イメージをビルドしておきましょう。
$ docker-compose build ... Successfully tagged handson_web:latest
docker-compose buildコマンドはdocker-compose.ymlでDockerfileからのビルドが必要なサービスのイメージビルドをすべて実行してくれます。今回はdbは DockerHub のイメージを使っているのでwebのみがビルドが必要なサービスとしてビルドされます。DBの接続設定
ビルドが終わったら、Rails アプリケーションの DB 接続設定をコーディングしていきます。 DB の接続設定は
config/database.ymlに記載します。 Rails では設定系のファイルはconfigディレクトリに格納されています。config/database.yml... default: &default adapter: postgresql encoding: unicode host: db username: postgres password: pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> ...
host、username、passwordがデフォルトから新たに追加した項目です。
hostはDBのホスト名です。今 Rails アプリが稼働しているwebコンテナはdocker-compose.ymlが作る Docker ネットワークの中にいます。この中ではサービス名で名前解決してコンテナが相互に接続することができます。つまりhostとしてdbを設定することでdocker-compose.ymlでdbのサービス名で定義されたコンテナに接続できるようになるのです。
usernameとpasswordは何の値なのでしょうか?これはdbコンテナのイメージで指定したpostgresのデフォルト値です。passwordは同じホストからのアクセスであれば省略が可能になっています。postgresイメージのusernameとpasswordはそれぞれPOSTGRES_USERとPOSTGRES_PASSWORDの環境変数で定義することもできます。データベースの設定はここまでです。このデフォルトの設定値が開発環境(
development)、テスト環境(test)の設定値として反映されるようになっています。データベースを作成する
データベースの接続設定を定義したので、データベースを実際に作成していきます。
Rails ではデフォルトで本番環境(production)、開発環境(development)、テスト環境(test)の3つの環境(environment)が用意されています。特別に環境を指定しない場合、開発環境で挙動するようになっています。
データベースの作成はrails db:createコマンドを使いますが、このコマンドは開発環境とテスト環境用にデータベースを作成してくれます。本番環境用のデータベースを作成する場合は、RAILS_ENV=productionをオプションとしてつけます。
今回はまず開発環境向けにデータベースの作成を行いたいので、以下のコマンドを実行します。$ docker-compose run --rm rails db:createHello Ruby on Rails on Docker!!
ここまでで Hello world に必要な作業は全て完了しました。
コンテナを立ち上げて Hello world ページが表示されることを確認しましょう。$ docker-compose up -dRails アプリは少し起動に時間がかかります。すぐに
http://localhost:3000にアクセスしてもまだアプリケーションが起動していないこともありますので、その場合はdocker-compose logsコマンドを使ってアプリケーションの起動状態を確認してみましょう。$ docker-compose logs -f
-fオプションはログの変化をリアルタイムでコンソールに表示するためのオプションです。Rails アプリが起動した場合web_1 | Use Ctrl+C to stopというログが表示されます。この表示を確認したら
Ctrl+Cでdocker-compose logsから抜け出しましょう。では、
http://localhost:3000にアクセスしてみましょう!
このようなページが表示されたでしょうか?このページが Rails アプリケーションの第一歩、つまり Hello world です。おめでとうございます!これでもう『Rails は Hello world までならやったことあります』と自慢することができます!ここまでできたら後片付けをしておきましょう。
このままではコンテナが起動しっぱなしになってしまうので、最後にコンテナを停止させておきます。$ docker-compose downこれでコンテナを停止させたので、
http://localhost:3000にアクセスしても先ほどのページは表示されなくなっていることでしょう。まとめ
今回は、
Dockerfileやdocker-compose.ymlなどのファイルを作成し、Rails アプリケーションを稼働させられる Docker イメージ、Docker コンテナを作成してみました。
さらに、Rails アプリを新規作成して Hello world に成功しました!
まだまだアプリケーション開発のほんの入り口ですが、Docker を使って Web アプリを起動させることができただけでもかなり感動があると思いますし、ここまでさほど大変ではないことも感じてもらえたかなと思います。これこそが Rails や Docker の偉大なところですね。次回は、
scaffoldという Rails の便利機能を使って、サンプル Web アプリケーションを作ってみようと思います。このscaffoldで作成できるアプリケーションが Rails の基本的なアプリケーションの形になりまして、その中には Rails アプリケーションを語る上では避けられないRESTfulやMVCの要素が詰まっていますので、その辺りも合わせて学んでいけるようにしようと思います。では、次回も乞うご期待!ここまでお読みいただきありがとうございました!
Reference
P.S. 間違っているところ、抜けているところ、説明の仕方を変えるとよりわかりやすくなるところなどありましたら、優しくアドバイスいただけると助かります。
- 投稿日:2020-02-04T12:04:29+09:00
Rails6 のちょい足しな新機能を試す 119(filter_paramters 編)
はじめに
Rails 6 に追加された新機能を試す第119段。 今回は、
filter_parameters編です。
Rails 6 では、 filter_parameters で proc を使って、フィルターしたときに、パラメータが配列になっているときに、フィルターされないというバグが修正されています。Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)
$ rails --version Rails 6.0.2.1今回は、User を2つ登録する画面を作って、その動作を確認します。
なお、filter_parametersの動作を確認するための手抜き実装になってます。Rails プロジェクトを作る
Rails プロジェクトを新たに作成します。
$ rails new rails_sandbox $ cd rails_sandboxUser モデルを作る
nameを持つ User モデルを作成します。$ bin/rails g model User nameController と View を作る
User の controller と View を作ります。 View は手抜き実装で、 一覧画面 (index) と 登録画面 (new) だけです。
$ bin/rails g controller Users index newroutes を定義する
User 用にルーティングを定義します。 これまた、手抜き実装で、
index,new,createの3つだけにします。config/routes.rbRails.application.routes.draw do resources :users, only: %i[index new create] end一覧画面 (index) を作成する
一覧画面を作成します。これまた、
tableタグも使わない手抜き実装です。
Userのnameを1件ずつ表示します。画面の下に、登録画面へのリンクを表示します。
app/views/users/index.html.erb<h1>Users#index</h1> <% @users.each do |user| %> <p> <%= user.name %> </p> <% end %> <%= link_to 'New', new_user_path %>登録画面 (new) を作成する
登録画面を作成します。ここで、今回の機能を試すためにパラメータの値が配列になるようにします。
(結果として2件のデータを登録することになります。)パラメータが配列となるように、
form.text_fieldの引数がname="names[]"としていることに注意してください。
これが、今回の機能を試すために必要なことの1つです。app/views/users/new.html.erb<h1>Users#new</h1> <%= form_with url: users_path do |form| %> <p> <%= form.text_field name="names[]" %> </p> <p> <%= form.text_field name="names[]" %> </p> <%= form.submit %> <% end %>UsersController を完成させる
今回の機能を確認するために、完成させる必要は無いのですが、一応、動作するように実装します。
これまた、手抜き実装です。
indexメソッドでは、全データを取得します。
createメソッドでは、パラメータを元にして User をデータベースに保存し、一覧画面にリダイレクトします。app/controllers/users_controller.rbclass UsersController < ApplicationController def index @users = User.all end def new end def create params[:names].each do |name| User.create(name: name) end redirect_to users_path end endfilter_parameters を指定して、 names パラメータの値がフィルタリングさせる
いよいよ、今回の機能を確認するために、
filter_parametersでnamesパラメータの値をフィルタリングさせます。proc を追加していることに注意してください。
config/application.rb... module App class Application < Rails::Application ... config.filter_parameters << lambda do |key, value| if key =~ /names/ value.replace('[FILTERED]') if value.respond_to?(:replace) end end end endマイグレーションを実行する
$ bin/rails db:create db:migraterails server を実行して、登録画面から登録する
bin/rails sを実行し、http://localhost:3000/users/newにアクセスし、2つのフィールドに適当に入力して、Saveボタンを押します。このとき、コンソールでは、
namesパラメータが、[FILTERED]となっていることに注意してください。Started POST "/users" for 192.168.16.1 at 2020-01-25 02:48:55 +0000 Processing by UsersController#create as JS Parameters: {"authenticity_token"=>"..., "names"=>["[FILTERED]", "[FILTERED]"], "commit"=>"Save "} (0.2ms) BEGINRails5 では
Rails 5.2.4.1 では、 フィルターされず、そのまま画面で入力した値が表示されてしまいます。
Started POST "/users" for 192.168.0.1 at 2020-01-25 01:42:25 +0000 Processing by UsersController#create as JS Parameters: {"utf8"=>"✓", "authenticity_token"=>"..., "names"=>["aaa", "bbb"], "commit"=>"Save "}あくまで手抜きのコードです
実際のアプリでは、複数のデータを1つの画面で登録する場合には、 Form オブジェクトを使ったり、Validation を追加したり、Strong Paramters を使ったりすると思います。
今回は、あくまでも、機能の確認のための実装なので、そういった点は、すっとばして、手を抜いてます。
このままコードを再利用することはオススメしません。試したソース
https://github.com/suketa/rails_sandbox/tree/try119_filter_parameters_proc
参考情報


