20200724のRailsに関する記事は10件です。

Ruby on Rails チュートリアル(第4版) 第12章

12.1.1 演習

1.この時点で、テストスイートが greenになっていることを確認してみましょう。
 省略

2.表 12.1の名前付きルートでは、_pathではなく_urlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: アカウント有効化で行った演習 (11.1.1.1) と同じ理由です。
 メールでURLを送付するから。

12.1.2 演習

1.リスト 12.4のform_forメソッドでは、なぜ@password_resetではなく:password_resetを使っているのでしょうか? 考えてみてください。
 よく分からなかったので、Railsのform_forにシンボルを与えるときはどのようなときか?こちらを参考に。
 複数のビューでform_forメゾット使う時に使い分けてくれるって感じなのかな?

12.1.3 演習

1.試しに有効なメールアドレスをフォームから送信してみましょう (図 12.6)。どんなエラーメッセージが表示されたでしょうか?
 wrong number of arguments (given 1, expected 0)

2.コンソールに移り、先ほどの演習課題で送信した結果、(エラーと表示されてはいるものの) 該当するuserオブジェクトにはreset_digestとreset_sent_atがあることを確認してみましょう。また、それぞれの値はどのようになっていますか?

 SQL (2.5ms)  UPDATE "users" SET "reset_digest" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["reset_digest", "$2a$10$HBKO270gNm.cJbXLUiK42.kbtr6rHK54A5shhjJ3AuyxdZ8CwKR2G"], ["updated_at", "2020-07-23 14:35:37.103987"], ["id", 1]]
   (7.2ms)  commit transaction
   (0.0ms)  begin transaction
  SQL (1.5ms)  UPDATE "users" SET "updated_at" = ?, "reset_sent_at" = ? WHERE "users"."id" = ?  [["updated_at", "2020-07-23 14:35:37.129134"], ["reset_sent_at", "2020-07-23 14:35:37.128433"], ["id", 1]]

12.2.1 演習

1.ブラウザから、送信メールのプレビューをしてみましょう。「Date」の欄にはどんな情報が表示されているでしょうか?
 Date:Thu, 23 Jul 2020 14:43:18 +0000

2.パスワード再設定フォームから有効なメールアドレスを送信してみましょう。また、Railsサーバーのログを見て、生成された送信メールの内容を確認してみてください。

    <h1>Password reset</h1>

<p>To reset your password click the link below:</p>

<a href="https://f85f995d89d545089c7ba0ef0e279d4c.vfs.cloud9.ap-northeast-1.amazonaws.com/password_resets/IcIj_J0Zlrd0_hygj_87Nw/edit?email=example%40railstutorial.org">Reset password</a>

<p>This link will expire in two hours.</p>

<p>
If you did not request your password to be reset, please ignore this email and
your password will stay as it is.
</p>
  </body>

3.コンソールに移り、先ほどの演習課題でパスワード再設定をしたUserオブジェクトを探してください。オブジェクトを見つけたら、そのオブジェクトが持つreset_digestとreset_sent_atの値を確認してみましょう。

>> user = User.find_by(id:1)
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2020-07-18 13:20:13", updated_at: "2020-07-23 14:41:35", password_digest: "$2a$10$9v5S4oJk16x9pfbMXkf/ievaQhPA50XBMqFztNrZnqj...", remember_digest: nil, admin: true, activation_digest: "$2a$10$OBqUPKe0HwaDUBtqARDRzO9NSFaoKAPHmjNzuTvoqz1...", activated: true, activated_at: "2020-07-18 13:20:13", reset_digest: "$2a$10$fAY5aKaX/6mcO7tbFS/AZOWhoYOcj3CgMvjiRgx/AEd...", reset_sent_at: "2020-07-23 14:41:35">

1.メイラーのテストだけを実行してみてください。このテストは greenになっているでしょうか?
 GREEN。

2.リスト 12.12にある2つ目のCGI.escapeを削除すると、テストが redになることを確認してみましょう。
 REDになった。

12.3.1 演習

1.12.2.1.1で示した手順に従って、Railsサーバーのログから送信メールを探し出し、そこに記されているリンクを見つけてください。そのリンクをブラウザから表示してみて、図 12.11のように表示されるか確かめてみましょう
 省略

2.先ほど表示したページから、実際に新しいパスワードを送信してみましょう。どのような結果になるでしょうか?

 Unknown action
 The action 'update' could not be found for PasswordResetsController
 エラーでドキッ!updateアクションまだ書いてないもんね。

12.3.2 演習

1.12.2.1.1で得られたリンク (Railsサーバーのログから取得) をブラウザで表示し、passwordとconfirmationの文字列をわざと間違えて送信してみましょう。どんなエラーメッセージが表示されるでしょうか?
 Password confirmation doesn't match Password

2.コンソールに移り、パスワード再設定を送信したユーザーオブジェクトを見つけてください。見つかったら、そのオブジェクトのpassword_digestの値を取得してみましょう。次に、パスワード再設定フォームから有効なパスワードを入力し、送信してみましょう (図 12.13)。パスワードの再設定は成功したら、再度password_digestの値を取得し、先ほど取得した値と異なっていることを確認してみましょう。ヒント: 新しい値はuser.reloadを通して取得する必要があります。

 password_digest: "$2a$10$B6393nyZgIhwI4l1sFvZqe7ut877uijFjhDoVSizLdy..."
 password_digest: "$2a$10$qFFzrhOelczLx3DO.2p6quDaFlV5T1ciSrCbDXTe44d..."

12.3.3 演習

1.リスト 12.6にあるcreate_reset_digestメソッドはupdate_attributeを2回呼び出していますが、これは各行で1回ずつデータベースへ問い合わせしていることになります。リスト 12.20に記したテンプレートを使って、update_attributeの呼び出しを1回のupdate_columns呼び出しにまとめてみましょう (これでデータベースへの問い合わせが1回で済むようになります)。また、変更後にテストを実行し、 greenになることも確認してください。ちなみにリスト 12.20にあるコードには、前章の演習 (リスト 11.39) の解答も含まれています。
 update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)

2.リスト 12.21のテンプレートを埋めて、期限切れのパスワード再設定で発生する分岐 (リスト 12.16) を統合テストで網羅してみましょう (12.21 のコードにあるresponse.bodyは、そのページのHTML本文をすべて返すメソッドです)。期限切れをテストする方法はいくつかありますが、リスト 12.21でオススメした手法を使えば、レスポンスの本文に「expired」という語があるかどうかでチェックできます (なお、大文字と小文字は区別されません)。
 assert_match /expired/i, response.body

3.2時間経ったらパスワードを再設定できなくする方針は、セキュリティ的に好ましいやり方でしょう。しかし、もっと良くする方法はまだあります。例えば、公共の (または共有された) コンピューターでパスワード再設定が行われた場合を考えてみてください。仮にログアウトして離席したとしても、2時間以内であれば、そのコンピューターの履歴からパスワード再設定フォームを表示させ、パスワードを更新してしまうことができてしまいます (しかもそのままログイン機構まで突破されてしまいます!)。この問題を解決するために、リスト 12.22のコードを追加し、パスワードの再設定に成功したらダイジェストをnilになるように変更してみましょう5 。
 省略

4.リスト 12.18に1行追加し、1つ前の演習課題に対するテストを書いてみましょう。ヒント: リスト 9.25のassert_nilメソッドとリスト 11.33のuser.reloadメソッドを組み合わせて、reset_digest属性を直接テストしてみましょう。
  assert_nil user.reload.reset_digest

12.4 演習

1.production環境でユーザー登録を試してみましょう。ユーザー登録時に入力したメールアドレスにメールは届きましたか?
 省略
2.メールを受信できたら、実際にメールをクリックしてアカウントを有効化してみましょう。また、Heroku上のログを調べてみて、有効化に関するログがどうなっているのか調べてみてください。ヒント: ターミナルからheroku logsコマンドを実行してみましょう。
 省略
3.アカウントを有効化できたら、今度はパスワードの再設定を試してみましょう。正しくパスワードの再設定ができたでしょうか?
 We're sorry, but something went wrong.
 If you are the application owner check the logs for more information.
 エラーが出てしまった。heroku logsで確認してもエラー確認出来ず。メール送ったことになってる。
 
 $ heroku run rails db:migrateをもう一度やってみる。ダメ。
 $ heroku run rake db:seedもやってみる。ダメ。
 DBをリセットしてみた。
 やっぱり駄目だった・・・どうして。

 ローカル環境では問題ない、エラーが出るのはメールが送信される時だけなのでSendGrid凍結の疑い。
 Railsチュートリアル11章 SendGrid 凍結問題を解決する
 こちらを参考に新しくデプロイし直ししたら無事解決!また凍結されるかもしれないけれども。
 なんとか無事に12章終わり!

メモ

- user.reloadで新しい値を取得できる(Rails console)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

deviseのビューファイルに自動でbootstrapのスタイルを適用する

結論

$ rails g devise:views:bootstrap_templates -f

これで全てのdeviseのビューファイルに、自動でbootstrapのスタイルが適用される。
アカウント.png
ログイン.png
パスワード.png

もうちょっと整える

deviseのビューファイルにデフォで記述されているコードを

<div class="container">
  <div class="row">
    <div class="mx-auto" style="width: 580px;">

    </div>
  </div><!-- End of row -->
</div><!-- End of container -->

これで囲ってあげると、
アカウント登録(中央).png
ログイン(中央).png
パスワード(中央).png

いい感じ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

sessionを使い遷移元の1つ前のページに戻る方法

こんな人におすすめ

こういうことがしたい人。
戻るボタンを押してブラウザの2つ前のページに戻りたい。
200724_session_01.png

環境

ruby 2.5.1
Rails 5.0.7.2

さっそく結論

sessionを使いましょう。

今回の経緯

  • 購買機能のあるWEBサイトを作成していた(payjpを利用)
  • 商品の詳細を表示してそのまま購入できる機能を持たせた
  • ただしクレジットカードを登録していない場合は以下のページ遷移としたい

200724_session_01.png

※上の図の左の1から右の3へいく流れ

1.商品の確認ページで購入ボタンを押す
2.購入完了の前にクレジットカード登録ページ遷移してカード登録をする
3.『この情報で登録したよ』という確認のページに遷移する

問題点

戻るボタンを押すとひとつ前のカード登録ページに戻ってしまう
(正確にはカード登録ページからリダイレクトされるページに戻ってしまう)

【解決策】 sessionを使って遷移元の1つ前のリファラーを保持しよう

全体像

class CardsController < ApplicationController

  require "payjp"

  before_action :sign_in_required
  after_action :session_clear, only: [:show]

  def new
    session[:previous_url] = request.referer
  # 〜以下省略〜
  end

  def pay
    # 〜省略〜 カード登録のコードが入ります
  end

  def delete
    # 〜省略〜 カード削除後のコードが入ります
  end

  def show 
    @session = session[:previous_url]
    # 〜省略〜 カード登録後のコードが入ります
  end

  private

  def sign_in_required
    # 〜省略〜 ユーザー登録していない場合はユーザー登録ページに遷移するコードが入ります
  end

  def session_clear
    session[:previous_url].clear
  end

end

今回使ったcontroller内のコード抜粋

初めてカード登録をする際に定義しているnewアクションに記述

# URLを保存する処理
# sessionにひとつ前のリファラーをいれる 
session[:previous_url] = request.referer

:previous_urlというのはdeviseを入れている場合は記述するだけで利用できます。
request.refererというのは、ひとつ前のURL(つまり遷移元URL)を取得するものです。

カード登録確認画面のshowアクションに記述

# sessionの中からURLを取り出してリダイレクトさせる
@session = session[:previous_url]

viewで使い回したいので代入したものにさらに代入してインスタンスを生成します。

新しくsession_clearアクションを記述してafter_actionで呼び出す

# sessionをクリア
session[:previous_url].clear

蓄積されたsession解放してあげたほうがセイキュリティ上でも良いとされています。

これで、理想の遷移元に戻ることができました。
200724_session_01.png

おわり。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【cygwin】Redmineをインストール

参考ページ一覧

留意点

  • 現在(2020-07-24)、bundleがバージョンアップを見据えた対応している。
  • この関係もあり、古い情報は rubygem, bundle に注意

ダウンロードファイル一覧

  • redmine-4.1.1.tar.gz
  • rubygems-3.1.4.tgz

cygwinパッケージ一覧

  • rubygemインストールで必要
    • ruby, ruby-devel
  • bundle installに必要
    • mysql-devel, libsqlite3-devel
  • nokogiriのインストールに必要
    • libxml2-devel, libxslt-devel

各バージョン

name version installation
ruby 2.6.4p104 cygwin
rubygem 3.1.4 rubygems-3.1.4.tgz
rails 6.0.3.2 gem
redmine 4.1.1 redmine-4.1.1.tar.gz

インストール手順

rubygems

$ tar xvzf rubygems-3.1.4.tgz
$ cd rubygems-3.1.4
$ ruby setup.rb
  • /usr/bin/gem, /usr/bin/bundle がインストールされます。

redmine

redmine動作環境に必要なパッケージの情報として、 GemFileredmine-4.1.1.tgz に含まれています。

以下はHOMEから始まります

$ tar xvzf src/redmine-4.1.1.tar.gz
$ cd redmine-4.1.1/conf
$ cp configuration.yml.example configuration.yml
$ cp database.yml.example database.yml
$ vi configuration.yml
$ vi database.yml
  • configuration.ymlの設定箇所
    • scm_subversion_command 設定例通りに設定
    • scm_cvs_command 設定例通りに設定
    • scm_cvs_path_regexp 一つあるcvs repositoryのフルパス
    • scm_stderr_log_file 設定例通りに設定
  • database.ymlの設定箇所
    • mysql2 を無効にして sqlite3 を有効にした。
      • 利用者1名のため

以降に継続

$ bundle config without 'development test' --local
$ vi .bundle/config
  • --local をつけ忘れると ~/.bundle/config に保存される

以降に継続

$ bundle lock --add-platform x86-mingw32 x64-mingw32 x86-mswin32
  • 結果として、 "GemFile.lock"が作成される。

以降に継続

$ bundle install
$ bundle update
$ bundle config build.nokogiri --use-system-libraries --local
$ bundle install
$ bundle update
$ bundle exec rake generate_secret_token
$ RAILS_ENV=production bundle exec rake db:migrate
$ RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data

remine立ち上げ

bundle exec rails server webrick -e production

localhost:3000にアクセス

課題

  • ImageMagickのインストール

参考

rubygemインストールの様子(要点のみ)

$ ruby setup.rb
  Successfully built RubyGem
  Name: bundler
  Version: 2.1.4
  File: bundler-2.1.4.gem
Bundler 2.1.4 installed
RubyGems 3.1.4 installed
Regenerating binstubs
Parsing documentation for rubygems-3.1.4
Installing ri documentation for rubygems-3.1.4

…

------------------------------------------------------------------------------

RubyGems installed the following executables:
        /usr/bin/gem
        /usr/bin/bundle

Ruby Interactive (ri) documentation was installed. ri is kind of like man
pages for Ruby libraries. You may access it like this:
  ri Classname
  ri Classname.class_method
  ri Classname#instance_method
If you do not wish to install this documentation in the future, use the
--no-document flag, or set it as the default in your ~/.gemrc file. See
'gem help env' for details.

bundle実行時の警告

参考にしたページに倣って bundle install --without development test を実行すると以下のメッセージが黄色で表示される。

$ bundle install --without development test
[DEPRECATED] The `--without` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set without 'development test'`, and stop using this flag
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, x64-mingw32, x86-mswin32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x64-mingw32 x86-mswin32`.
The dependency ffi (>= 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, x64-mingw32, x86-mswin32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x64-mingw32 x86-mswin32`.

rubygemインストールの様子(詳細)

$ ruby setup.rb
  Successfully built RubyGem
  Name: bundler
  Version: 2.1.4
  File: bundler-2.1.4.gem
Bundler 2.1.4 installed
RubyGems 3.1.4 installed
Regenerating binstubs
Parsing documentation for rubygems-3.1.4
Installing ri documentation for rubygems-3.1.4

=== 3.1.4 / 2020-06-03

Minor enhancements:

* Deprecate rubyforge_project attribute only during build
  time. Pull request #3609 by Josef Šimánek.
* Update links. Pull request #3610 by Josef Šimánek.
* Run CI at 3.1 branch head as well. Pull request #3677 by Josef Šimánek.
* Remove failing ubuntu-rvm CI flow. Pull request #3611 by
  Josef Šimánek.

=== 3.1.3 / 2020-05-05

Minor enhancements:

* Resolver: require NameTuple before use. Pull request #3171 by Olle
  Jonsson.
* Use absolute paths with autoload. Pull request #3100 by David Rodríguez.
* Avoid changing $SOURCE_DATE_EPOCH. Pull request #3088 by Ellen Marie
  Dash.
* Use Bundler 2.1.4. Pull request #3072 by Hiroshi SHIBATA.
* Add tests to check if Gem.ruby_version works with ruby git master.
  Pull request #3049 by Yusuke Endoh.

Bug fixes:

* Fix platform comparison check in #contains_requirable_file?. Pull
  request #3495 by Benoit Daloze.
* Improve gzip errors logging. Pull request #3485 by David Rodríguez.
* Fix incorrect `gem uninstall --all` message. Pull request #3483 by David
  Rodríguez.
* Fix incorrect bundler version being required. Pull request #3458 by
  David Rodríguez.
* Fix gem install from a gemdeps file with complex dependencies.
  Pull request #3054 by Luis Sagastume.

=== 3.1.2 / 2019-12-20

Minor enhancements:

* Restore non prompting `gem update --system` behavior. Pull request #3040
  by David Rodríguez.
* Show only release notes for new code installed. Pull request #3041 by
  David Rodríguez.
* Inform about installed `bundle` executable after `gem update --system`.
  Pull request #3042 by David Rodríguez.
* Use Bundler 2.1.2. Pull request #3043 by SHIBATA Hiroshi.

Bug fixes:

* Require `uri` in source.rb. Pull request #3034 by mihaibuzgau.
* Fix `gem update --system --force`. Pull request #3035 by David
  Rodríguez.
* Move `require uri` to source_list. Pull request #3038 by mihaibuzgau.

=== 3.1.1 / 2019-12-16

Bug fixes:

* Vendor Bundler 2.1.0 again. The version of Bundler with
  RubyGems 3.1.0 was Bundler 2.1.0.pre.3. Pull request #3029 by
  SHIBATA Hiroshi.


------------------------------------------------------------------------------

RubyGems installed the following executables:
        /usr/bin/gem
        /usr/bin/bundle

Ruby Interactive (ri) documentation was installed. ri is kind of like man
pages for Ruby libraries. You may access it like this:
  ri Classname
  ri Classname.class_method
  ri Classname#instance_method
If you do not wish to install this documentation in the future, use the
--no-document flag, or set it as the default in your ~/.gemrc file. See
'gem help env' for details.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【cygwin】Redmineを動かす

留意点

  • 現在(2020-07-24)、bundleがバージョンアップを見据えた対応している。
    • この関係もあり、古い情報は rubygem, bundle に注意
  • 個人で利用することを前提に、sqlite3を利用する。

ダウンロードファイル一覧

  • redmine-4.1.1.tar.gz
  • rubygems-3.1.4.tgz

cygwinパッケージ一覧

  • rubygemインストールで必要
    • ruby, ruby-devel
  • bundle installに必要
    • mysql-devel, libsqlite3-devel
  • nokogiriのインストールに必要
    • libxml2-devel, libxslt-devel

各バージョン

name version installation
ruby 2.6.4p104 cygwin
rubygem 3.1.4 rubygems-3.1.4.tgz
rails 6.0.3.2 gem
redmine 4.1.1 redmine-4.1.1.tar.gz

インストール手順

rubygems

$ tar xvzf rubygems-3.1.4.tgz
$ cd rubygems-3.1.4
$ ruby setup.rb
  • /usr/bin/gem, /usr/bin/bundle がインストールされます。

redmine

redmine動作環境に必要なパッケージの情報として、 GemFileredmine-4.1.1.tgz に含まれています。

以下はHOMEから始まります

$ tar xvzf src/redmine-4.1.1.tar.gz
$ cd redmine-4.1.1/conf
$ cp configuration.yml.example configuration.yml
$ cp database.yml.example database.yml
$ vi configuration.yml
$ vi database.yml
  • configuration.ymlの設定箇所
    • scm_subversion_command 設定例通りに設定
    • scm_cvs_command 設定例通りに設定
    • scm_cvs_path_regexp 一つあるcvs repositoryのフルパス
    • scm_stderr_log_file 設定例通りに設定
  • database.ymlの設定箇所
    • mysql2 を無効にして sqlite3 を有効にした。
      • 利用者1名のため

以降に継続

$ bundle config without 'development test' --local
$ vi .bundle/config
  • --local をつけ忘れると ~/.bundle/config に保存される

以降に継続

$ bundle lock --add-platform x86-mingw32 x64-mingw32 x86-mswin32
  • 結果として、 "GemFile.lock"が作成される。

以降に継続

$ bundle install
$ bundle update
$ bundle config build.nokogiri --use-system-libraries --local
$ bundle install
$ bundle update
$ bundle exec rake generate_secret_token
$ RAILS_ENV=production bundle exec rake db:migrate
$ RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data

remine立ち上げ

bundle exec rails server webrick -e production

localhost:3000にアクセス

課題

  • ImageMagickのインストール

参考

rubygemインストールの様子(要点のみ)

$ ruby setup.rb
  Successfully built RubyGem
  Name: bundler
  Version: 2.1.4
  File: bundler-2.1.4.gem
Bundler 2.1.4 installed
RubyGems 3.1.4 installed
Regenerating binstubs
Parsing documentation for rubygems-3.1.4
Installing ri documentation for rubygems-3.1.4

…

------------------------------------------------------------------------------

RubyGems installed the following executables:
        /usr/bin/gem
        /usr/bin/bundle

Ruby Interactive (ri) documentation was installed. ri is kind of like man
pages for Ruby libraries. You may access it like this:
  ri Classname
  ri Classname.class_method
  ri Classname#instance_method
If you do not wish to install this documentation in the future, use the
--no-document flag, or set it as the default in your ~/.gemrc file. See
'gem help env' for details.

bundle実行時の警告

参考にしたページに倣って bundle install --without development test を実行すると以下のメッセージが黄色で表示される。

$ bundle install --without development test
[DEPRECATED] The `--without` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set without 'development test'`, and stop using this flag
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, x64-mingw32, x86-mswin32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x64-mingw32 x86-mswin32`.
The dependency ffi (>= 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, x64-mingw32, x86-mswin32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x64-mingw32 x86-mswin32`.

rubygemインストールの様子(詳細)

$ ruby setup.rb
  Successfully built RubyGem
  Name: bundler
  Version: 2.1.4
  File: bundler-2.1.4.gem
Bundler 2.1.4 installed
RubyGems 3.1.4 installed
Regenerating binstubs
Parsing documentation for rubygems-3.1.4
Installing ri documentation for rubygems-3.1.4

=== 3.1.4 / 2020-06-03

Minor enhancements:

* Deprecate rubyforge_project attribute only during build
  time. Pull request #3609 by Josef Šimánek.
* Update links. Pull request #3610 by Josef Šimánek.
* Run CI at 3.1 branch head as well. Pull request #3677 by Josef Šimánek.
* Remove failing ubuntu-rvm CI flow. Pull request #3611 by
  Josef Šimánek.

=== 3.1.3 / 2020-05-05

Minor enhancements:

* Resolver: require NameTuple before use. Pull request #3171 by Olle
  Jonsson.
* Use absolute paths with autoload. Pull request #3100 by David Rodríguez.
* Avoid changing $SOURCE_DATE_EPOCH. Pull request #3088 by Ellen Marie
  Dash.
* Use Bundler 2.1.4. Pull request #3072 by Hiroshi SHIBATA.
* Add tests to check if Gem.ruby_version works with ruby git master.
  Pull request #3049 by Yusuke Endoh.

Bug fixes:

* Fix platform comparison check in #contains_requirable_file?. Pull
  request #3495 by Benoit Daloze.
* Improve gzip errors logging. Pull request #3485 by David Rodríguez.
* Fix incorrect `gem uninstall --all` message. Pull request #3483 by David
  Rodríguez.
* Fix incorrect bundler version being required. Pull request #3458 by
  David Rodríguez.
* Fix gem install from a gemdeps file with complex dependencies.
  Pull request #3054 by Luis Sagastume.

=== 3.1.2 / 2019-12-20

Minor enhancements:

* Restore non prompting `gem update --system` behavior. Pull request #3040
  by David Rodríguez.
* Show only release notes for new code installed. Pull request #3041 by
  David Rodríguez.
* Inform about installed `bundle` executable after `gem update --system`.
  Pull request #3042 by David Rodríguez.
* Use Bundler 2.1.2. Pull request #3043 by SHIBATA Hiroshi.

Bug fixes:

* Require `uri` in source.rb. Pull request #3034 by mihaibuzgau.
* Fix `gem update --system --force`. Pull request #3035 by David
  Rodríguez.
* Move `require uri` to source_list. Pull request #3038 by mihaibuzgau.

=== 3.1.1 / 2019-12-16

Bug fixes:

* Vendor Bundler 2.1.0 again. The version of Bundler with
  RubyGems 3.1.0 was Bundler 2.1.0.pre.3. Pull request #3029 by
  SHIBATA Hiroshi.


------------------------------------------------------------------------------

RubyGems installed the following executables:
        /usr/bin/gem
        /usr/bin/bundle

Ruby Interactive (ri) documentation was installed. ri is kind of like man
pages for Ruby libraries. You may access it like this:
  ri Classname
  ri Classname.class_method
  ri Classname#instance_method
If you do not wish to install this documentation in the future, use the
--no-document flag, or set it as the default in your ~/.gemrc file. See
'gem help env' for details.

リンク一覧

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActiveStorageをクラウドストレージ(GCS,S3, etc)で使ってた時に処理が遅くなる問題

概要

Heroku上で動かしていたRailsアプリの処理が遅かった時の調査メモです。
結論として、画像保存に使用していたGCPのクラウドストレージの部分がボトルネックとなっていました。

環境

  • Ruby 2.6.3p62
  • Rails 6.0.2.2

背景

Herokuの無料プランでRailsを使った趣味のWEBサイトを構築運用しています。
当初から処理はあまり早くないものの、SQLに関してもRedisでキャッシュを入れたりしていたので、まぁ無料ならこんなものかと思っていました。

しかしながら、一部のページのみ他のページより早い事に気がつき、何が原因かを調べることとしました。

調査

調査方法

一般的な方法ですが、下記のコマンドでログを出力させて処理時間を調べる事にしました。

heroku logs --tail

デフォルトでRailsはDEBUGログで処理時間を色々出してくれるので、まずはそこを確認する事にしました。

ログの調査結果

当初はキャッシュしていない部分のSQLが遅いのかと思っていましたが、
SQLに関してはキャッシュも効いて遅いクエリも見つかりませんでした。

しかしながら、代わりに下記のような処理時間に100ms以上かかっているログが何箇所が見受けられました。

 GCS Storage (169.9ms) Checked if file exists at key: variants/xxxx

該当のサイトは画像をGCSにアップロードしており、その部分が関連している事が推測できました。
また、variantといったキーワードからActiveStorageの該当機能が影響していることもわかります。

Variant

このvariantに関しては下記の参考資料などを見ていただければと思いますが簡単に言えば、アップロードした画像をそのまま使わずにリサイズ等を行う機能です。
参考

この機能を使えばわざわざ自分でリサイズ処理などを実装する必要がなく、更に初回アクセス時にリサイズした画像を保存して裏で再利用してくれてかなり便利な機能です。
ですが、今回はきの機能が何か悪影響を与えているようです。

ググってみる

これ以上の調査は難しいと判断し、とりあえず似たような症状が他でも起きているのかググってみました。

結果として、AWSのS3などで似たような症状と思われるものが何点か見つかりました。

https://stackoverflow.com/questions/49415911/activestorage-checking-if-file-exists-is-slow
https://github.com/rails/rails/issues/32548
https://github.com/rails/rails/pull/37901

拙い英語力で斜め読みした所、下記のように判断しました。
(間違っていたらすみません。)

  • 変換し保存した画像の存在チェックを行なっており、そこで時間がかかっている
  • 既に対応する修正を行なっており、Railsバージョン(6.1)に含まれる

解決方法

上記を見て、最新版にすれば解決するかと思いましたが、残念ながら6.1はまだリリースされていませんでした・・・。

結論として、varianによる圧縮処理をやめて元の画像を使用する事としました。
元の画像に関して、そもそもアップロード前に手動で画像ツール等でリサイズなどの補正をしているため問題にはならないだろうという判断です。

結果として元の100ms以上かかっていたログは消えて、下記のような1ミリ秒の処理に変更され、体感的に速度が早くなったように感じます。

GCS Storage (1.5ms) Generated URL for file at key: xxxx 

まとめ

という事で、クラウドストレージ(GCS)でActiveStorageで加工した画像を使用する際に処理時間がかかっている事が原因でした。
根本的な対策はせずに機能を使用しないという、微妙な形で対応する事としました。

いずれリリースされるRails6.1では対策がされているようなので、アップデート後にはまた機能を使用したいと思います。

S3やGCSなどクラウドストレージをお手軽に使用できるActive Storageですが、裏で色々と隠蔽してくれているおかげで、逆に見えない箇所で性能に影響を与える事がわかりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ElasticBeanstalkのアプリケーションログをCloudWatchで捕捉したい

サーバのログ問題ってあると思いますが、皆さんはどうされていますか?
よくあるパターンはfluentdで特定のログ保存用サーバに送るパターンだと思います。
他にもDatadogやInsight7でトラッキングする方法などありますが、いずれも設定が大変でエージェント仕掛けたりとかCloudFormation仕掛けたりとか挫折しやすいです(実際今回の記事書くときにもやってみたけど正直何度もサポートに聞く羽目になったし、仮に設定できても有料なのも痛い)。

あとdmsgとかアクセスログとかの保存は簡単だけど、アプリケーションログに関しては保存していないケースも多くて情報探すのにも苦労しました。

ElasticBeansTalkで作成したサーバのアプリケーションログは1時間とかでローテーションしてしかも消えてしまったり、AWSの管理画面でログのダウンロードしても出てこなかったりという問題があります。

ローカルでテストしているときはエラーのハンドリングは難しくないけど、本番じゃないと発生しない問題にはどう対処すればいいのか悩ましいところです。エラーのトラッキングはSentryも仕掛けているけど例外発生のときくらいしか拾わないのでなかなか使いにくいというのもあります。

長々すみません。ということでAWSでEC2(ElasticBeranstalk)使っているならCloudWatchでアプリケーションログ管理しようってことでチャレンジした内容になります。非常に簡単なので似たような環境をお持ちでしたらぜひご検討ください。

IAMにポリシーを追加

IAM-Management-Console.png

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:GetLogEvents",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams",
        "logs:PutRetentionPolicy"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

.ebextensionsにawslogsエージェントをインストール&設定する記述を追加

packages:
  yum:
    awslogs: []

files:
  "/etc/awslogs/awscli.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [plugins]
      cwlogs = cwlogs
      [default]
      region = `{"Ref":"AWS::Region"}`

  "/etc/awslogs/awslogs.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [general]
      state_file = /var/lib/awslogs/agent-state

  "/etc/awslogs/config/logs.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [/var/log/messages]
      log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/log/messages"]]}`
      log_stream_name = {instance_id}
      file = /var/log/messages
      [/var/log/dmesg]
      log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/log/dmesg"]]}`
      log_stream_name = {instance_id}
      file = /var/log/dmesg
      [/var/app/current/log/production.log]
      log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/app/current/log/production.log"]]}`
      log_stream_name = {instance_id}
      file = /var/app/current/log/production.log

commands:
  "01":
    command: chkconfig awslogs on
  "02":
    command: service awslogs restart

CloudWatchのロググループで確認

CloudWatch-Management-Console.png

なんとこれだけ、検索もできるしRails.loggerで仕掛けたログも引っ掛けやすい。是非試してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Elasticsearchを含むRspecのリクエストスペックを書いてみた

環境

railsとelasticsearchをそれぞれ別コンテナで動かしている

services:
  elasticsearch:
    image: elastcserachのdockerイメージ
    (以下省略)
  rails:
    image: railsのdockerイメージ
    (以下省略)

テスト用にGemを追加

テスト用のクラスタを別ポート(デフォルトは9250)で立ち上がることができる
https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-extensions

テスト用のクラスタを立ち上げる

elasticsearchを使うときだけ立ち上げ、終了したら止める

require 'elasticsearch/extensions/test/cluster'

before(:context) do
  Elasticsearch::Extensions::Test::Cluster.start(nodes: 1) unless Elasticsearch::Extensions::Test::Cluster.running?
end

after(:context) do
  Elasticsearch::Extensions::Test::Cluster.stop if Elasticsearch::Extensions::Test::Cluster.running?
end

実行したらエラーになる、、

Cannot find Elasticsearch launch script from [elasticsearch] -- did you pass a correct path?

elasticsearchとrailsのコンテナが違うので、railsのコンテナでelasticsearchを起動するには、railsのコンテナでelasticsearchを使えるようにしないといけないみたい。。。。

方向性を変えて、DB運用と同様に、テスト用のindexを用意する(先ほど追加したgemも削除)
ということで、alias_nameを環境ごとに分ける

def alias_name
  "players_#{Rails.env}"
end

今回扱うデータ

Playerという選手のidと名前をカラムに持つテーブルのデータを扱う

id name
1 xxxx
2 xxxx

下記のようにelasticsearchへ入れるデータを定義する

require 'elasticsearch/model'

module SearchablePlayer
  extend ActiveSupport::Concern

  included do
    include Elasticsearch::Model
    include Indexing

    index_name "players_#{Rails.env}_#{Time.now.strftime('%Y%m%d%H%M%S')}"

    settings do
      mappings dynamic: false do
        indexes :id, type: 'integer'
        indexes :name, type: 'string'
      end
    end
  end

  module Indexing
    def as_indexed_json(options={})
      {
        id: id,
        name: name,
      }
    end
  end

  module ClassMethods
    def alias_name
      "players_#{Rails.env}"
    end
  end
end

テスト用のクラスタにデータを入れる

rspec内にテーブルの中身をelasticsearchへ反映するためのメソッドを定義する
(elasticsearchへの反映には時間がかかるので、1秒sleepを入れる)
このとき、index名は「players_test」となるので、開発環境のindexには影響はない

def elasticsearch_update
  index_name = Player.index_name
  alias_name = Player.alias_name

  # Playerのindexを追加
  Player.__elasticsearch__.import(
    force: true,
    index: index_name
  )

  # Playerのindexを追加
  actions = [{
    add: {
      index: index_name,
      alias: alias_name
    }
  }]
  Player.__elasticsearch__.client.indices.update_aliases(
    body: { actions: actions }
  )
  # インデックスに反映するために1秒待つ
  sleep 1
end

リクエストスペックを書く

今回は選手の一覧を返却するAPIのテストを書く
beforeでテーブルにレコードを作成してから、先ほど定義したメソッドを呼ぶ

describe '選手の一覧を返却するAPI'
  before do
    # データを作成する
    FactoryBot.create(players, name: 'test')
    # 作成したデータをelasticsearchへ反映させる
    elasticsearch_update
  end
  it do
    get 選手一覧のAPIパス
    expect(レスポンスの選手名).to eq(test)
  end
end

テストが終わったらindexを削除する

このままだとテストを回すごとにindexが追加されていってしまうので、
テストが終わったらindexを削除する
また、elasticsearchへデータを投入しないパターンもあるので、
その場合にNotFoundの例外が起きるので、rescueする(もっといい方法があるかも、、)

after(:example) do
  player_client = Player.__elasticsearch__.client
  alias_name = Player.alias_name
  begin
    delete_indices = player_client.indices.get_alias(name: alias_name).keys
    player_client.indices.delete(index: delete_indices)
  rescue Elasticsearch::Transport::Transport::Errors::NotFound
  end
end

まとめ

gem(Elasticsearch::Extensions)が使えなかったが
DB運用のように、テスト用のindexを作ることで十分にテストを書くことができた。(特に弊害もなさそう?)

参考

https://techlife.cookpad.com/entry/2015/09/25/170000
https://blog.bitjourney.com/entry/2015/05/22/162250

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails Tutorial 第8章完了

2020/7/14 0.5時間

2020/7/15 0.5時間

8.1まで完了しました。

2020/7/16 0.5時間

||=の意味を理解するのに時間がかかりました。

2020/7/17 0.5時間

2020/7/18 2.5時間

土日は時間が取れ、平日より進められました。

2020/7/19 2時間

1.5時間で8章が終わりました。
残り0.5時間は9章です。

これで8章を完了しました。
所要時間は6時間です。

難易度が上がり、Ruby独特の表記の意味を理解するのに時間がかかりました。
毎日朝に少しずつが出来てきています。

別のブラウザで開くと「VFS connecion does not exist」エラー

Cloud9でやっています。
注11にある、

クラウドIDEをご利用の場合は、別のブラウザでログイン動作を確認することをおすすめします。そうでないと、クラウドIDEを開いているブラウザも一緒に閉じるはめになってしまいます。

に従い、環境を
・Cloud9はFirefox
・実行用にChromeブラウザ
としました。

Cloud9から開いたFirefoxのタブに表示されていたURLを、コピーして、ChromeにURLを打ち込んだところ、「VFS connecion does not exist」のエラーで開けませんでした。

クッキーが削除されたのかはFirefoxのツールでは分かりませんでした

他の人のサイトを調べたところ、Chromeでは分からないとの記載がありました。ですが、Firefoxの例は見つかりませんでした。
アプリ画面の上部のメニューを見るとログイン状態からログオフ状態に変わったので、動作は正しいように見えます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者がDockerで開発環境構築してみた(Rails&MySQL)

はじめに

現在、就職活動中のプログラミング初学者です。
開発環境にDockerを取り入れる為、いろいろ勉強して自分用のメモとしてまとめておりましたが、折角なら同じ初学者の方の役に立てればと思い投稿させて頂きます。既に多くの方がDockerの環境構築に関する記事を書かれており、そういった記事を参考にさせて頂きながら、メモとしてまとめていましたので、内容はそんなに目新しものではありません。予めご了承ください。また、誤った表現などがありましたらご指摘頂けると幸いです。

開発環境

  • Ruby 2.6.3
  • Rails 5.2.3
  • MySQL 5.7
  • MacOS 10.15.5

前提条件

  • Dockerhubのアカウントを作成している。
  • Docker for Macをインストールしている。
  • Dockerの基礎はある程度抑えている。

Dockerの基本的なことはこちらの記事が参考になります。
いまさらだけどDockerに入門したので分かりやすくまとめてみた

対象読者

今回は開発環境を構築することを目標とする為、Dockerに関する基礎的な部分はある程度抑えている方とします。

Railsの開発環境構築

DockerでRailsの開発環境を構築するには以下のファイルが必要になります。

  • Dockerfile
  • Gemfile
  • Gemfile.lock
  • docker-compose.yml

1.作成するアプリ名のディレクトリを作成する。

まずは、上記のファイルを作成するディレクトリを作成します。

#ターミナル
$ mkdir my-app

2.作成したディレクトリに移動する。

$ cd my-app

3.Dockerfileを作成する。

1.で作成したディレクトリ内にDockerfileを作成します。

$ touch Dockerfile

Dockerfileとは?

Dockerでは、dockerhubで公開されているimageを元にコンテナを起動することができるが、必要なパッケージや各種の設定を含んだDocker imageを自分で作成して使用したい場合が出てくる。その場合にDockerfileを用意して、それを元にDocker imageを作成することができる。
Dockerfileにはベースのimageに対して実行する内容を記述する。

4.Dockerfileに記述する。

Dockerfile
# ベースイメージ 今回はrubyのimage。
FROM ruby:2.6.3

# 必要なパッケージのインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs           

# 作業ディレクトリの作成、設定
RUN mkdir /my-app

#作業ディレクトリを指定している
WORKDIR /my-app

# ホスト側(ローカル)のGemfileを追加する(ローカルのGemfileは別途事前に作成しておく)
COPY ./Gemfile /my-app/Gemfile
COPY ./Gemfile.lock /my-app/Gemfile.lock

# Gemfileのbundle install
RUN bundle install
COPY . /my-app

5.Gemfileを作成する。

$ touch Gemfile

6.Gemfileに記述する。

Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.3'

7.空のGemfile.lockを作成する。

$ touch Gemfile.lock

8.docker-compose.ymlを作成する。

$ touch docker-compose.yml

Docker Composeとは?

Dockerでは1つのコンテナには、1つのアプリケーションのみを入れておき、複数のコンテナを組み合わせてサービスを構築するという方法が推奨されている。
Docker Composeは、複数のコンテナで構成されるアプリケーションについて、Docker imageのbuildや各コンテナの起動・停止などをより簡単に行えるようにするツール。

docker-compose.ymlとは?

Docker Composeを使用する際に必要となるファイルのこと。

docker-compose.ymlには以下の内容を定義します。

  • Docker imageをbuildするための情報(使用するDockerfile、image名など)
  • コンテナ起動するための情報(ホストとの共有ディレクトリ設定やポートフォワードなどの起動オプションなど)
  • 使用するDockerネットワーク など

9.docker-compose.ymlに記述する。

docker-compose.yml
version: '3' # バージョンを指定
services:
  db: # データベースサーバ用のコンテナの設定を記述
    image: mysql:5.7 # コンテナで使用するイメージ名を記述
    environment:
      MYSQL_ROOT_PASSWORD: password # 任意のパスワードを設定
      MYSQL_DATABASE: root # 任意のデータベース名を設定
    ports:
      - "3306:3306" # ホストの3306ポートとコンテナの3306ポートを接続する。
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql #ホストの./db/mysql/volumesをコンテナ内の/var/lib/mysqlにマウントする。Dockerのコンテナと、ローカルを同期している。コンテナを削除してもデータは永続化する。

  web: # アプリケーションサーバ用のコンテナの設定を記述
    build: . # docker-compose.ymlと同じ階層にあるDockerfileを使ってimageをbuildするための記述
    command: bundle exec rails s -p 3000 -b '0.0.0.0' # コンテナ立ち上げ時に起動するコマンド。railsを実行する。

    volumes:
      - .:/my-app # 作業ディレクトリをコンテナ内の/my-appにマウントする。
    ports:
      - "3000:3000" # ホストの3000ポートとコンテナの3000ポートを接続する。
    depends_on:
      - db # 依存関係を表している。dbが起動してからwebが起動するという意味。

10.コンテナを起動し、コンテナ内でrails newを実行する。

$ docker-compose run web rails new . --force --database=mysql --skip-bundle

runコマンドは、imageの構築から、コンテナの構築・起動まで行います。
また、runコマンドを介して引数で指定したサービスのコンテナ内でコマンドを実行できます。つまり、ここでは生成されたコンテナ内でrails newを行っています。
--forceオプションはファイルが存在する場合に上書きで作成するためのオプション。
--database=mysqlオプションは使用するデータベースの指定をするためのオプション。
--skip-bundleオプションはbundle installをスキップするためのオプション。

11.database.ymlを修正する。

rails newで作成されたデータベースの接続設定ファイルにはホスト名とパスワードが設定されていません。railsアプリケーションがデータベースに接続できるようにするため、database.ymlを修正します。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password # docker-compose.ymlのMYSQL_ROOT_PASSWORD
  host: db # docker-compose.ymlのservice名

12.buildを実行する。

$ docker-compose build

ここでbuildを実行する理由は10.で実行したコマンドによりGemfileの内容が書き換わっている為です。

13.Dockerを起動する。

$ docker-compose up -d # docker-compose.ymlを参照してコンテナが一斉起動する。

注意点としてここで実行するdocker-composeコマンドはdocker-compose.ymlを元に実行が進むので、docker-compose.ymlがあるディレクトリ上で実行する必要があります。

14.データベースを作成する。

docker-compose run webをコマンドの先頭につけることでコンテナ内でコマンドを実行できるので、

$ docker-compose run web rails db:create

を実行すれば、データベースが作成できます。

要は、docker-compose run webに続けていつものローカルで開発している時のコマンドが使えます。

では、localhost:3000に接続してみましょう。

以下の画面が表示されれば完了です。

gemを入れてbundle installしてみる。

開発環境が整ったので試しにgemを入れてbundle installしてみます。

Gemfile
gem 'devise'
$ docker-compose run web bundle install

そして、

$ docker-compose run web rails g devise:install

しかし以下のようなエラーが出ました。

Could not find bcrypt-3.1.15 in any of the sources
Run `bundle install` to install missing gems.

bundle installしたはずなのに。。。
これは12.のところと同じ現象です。つまり、ローカルで書き換えたGemfileがコンテナ内のGemfileに反映されていない。ここでは再度、docker-compose buildを行う必要があります。理由はDockerfileを見れば分かります。

Dockerfile
COPY ./Gemfile /my-app/Gemfile
COPY ./Gemfile.lock /my-app/Gemfile.lock

Dockerfile内でimageをbuildする際にローカル側のGemfileをコンテナ側にコピーしていました。ですから、現状ローカルのGemfileの変更はコンテナのGemfileには反映されていない訳です。これを反映させる為に、再度docker-compose buildを行う(imageをbuildし直す)必要があるという訳です。
では、再度docker-compose buildを実行します。

$ docker-compose build

もう一度、エラーが出たコマンドを試します。

$ docker-compose run web rails g devise:install

今度は上手く行きました。

しかし、gemを入れるたびに毎回docker-compose buildするのは面倒臭い。。。

という訳で、毎回docker-compose buildをしなくてもいいようにこちらの記事を参考にさせてもらい、docker-compose.ymlを編集します。
docker-composeでRailsのGemを更新する時、docker buildするのを回避したい

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "3306:3306"
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql

  web:
    build: . 
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/my-app
      - gem_data:/usr/local/bundle # ローカルのgem_dataをコンテナ内の/usr/local/bundleにマウントする。
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes: # 上記のvolumesのgem_dataはローカルのものを使うことを指定している。
  gem_data:

これで、gemをインストールするたびにdocker-compose buildをしなくてもよくなりました。

binding.pryをしたい時

docker-compose.ymlに以下を記述します。

docker-compose.yml
web:
  tty: true
  stdin_open: true

SequelProでデータベースを可視化する。

私はローカルで開発を行う際、SequelProを使用してデータベースを可視化していましたが、コンテナの仮想環境下では現状SequelProでデータベースを可視化することはできません。
docker-compose.ymlを以下の様に書き換えSequelProでデータベースを可視化できるよう設定していきます。

docker-compose.yml
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "4306:3306" # ホストの4306ポートをコンテナ内の3306ポートに接続するよう書き換える。
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql

次に、sequelpro起動時のモーダル内のタブを標準タブに切り替え、下記の通りに入力します。

名前: defaultのまま
ホスト: 127.0.0.1    # 自分自身を表すIPアドレス
ユーザー名: root    # database.ymlに記載のユーザー名
パスワード: password  # database.ymlに記載のパスワード
データベース: 空欄のまま
ポート: 4306      # docker-compose.ymlに記載したlocal側のports番号

これでdocker環境下でもデータベースが可視化できるようになります。

参考記事・参考動画

今回Dockerを学習するにあたり、多くの方の記事を参考にさせて頂きました。
ありがとうございました。
docker-compose コマンドまとめ
docker-compose up とか build とか start とかの違いを理解できていなかったのでまとめてみた。
既存のRailsアプリをDockerコンテナで動かす方法+sequel proによるDBコンテナ可視化
Dockerを使用したRails開発①(環境構築)
【rails環境構築】docker + rails + mysql で環境構築(初心者でも30分で完了!)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む