Open5
ROR環境構築
Ruby on Rails環境構築(Docker)
Your bundle only supports platforms [] but your local platform is x86_64-linux. Add the current platform to the lockfile with `bundle lock --add-platform
デプロイ先サーバーのOSをBundlerが実行できるプラットフォームに追加する
下記をDockerfileに追加するも動かず...。
RUN bundle lock --add-platform ruby
RUN bundle lock --add-platform x86_64-linux
結果こうしたらdocker-compose buildは通った。
FROM ruby:3.0.2
ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends sudo curl apt-transport-https wget build-essential libpq-dev nodejs default-mysql-client
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && \
apt-get install --no-install-recommends -y yarn
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle lock --add-platform x86_64-linux
RUN bundle install
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
その後、rails newする
$ docker-compose run app rails new . --force --database=mysql
Could not find mysql2-0.5.3 in any of the sources
mysql2-0.5.3のgemがないと言っている?
bundle installをやってみるも特にエラーも出ないので何が悪いのか謎
状況:
- bundle listを実行すると「Could not find mysql2-0.5.3 in any of the sources」のエラーが出る
- railsサーバ立ち上げでも「Could not find mysql2-0.5.3 in any of the sources」のエラーが出る
- Gemfile.lockには記載あり(mysql2 (0.5.3)
- gem listで確認するとmysql2は存在しない
- bundle installでもエラーは出ていない
$ docker-compose run app bundle install
Starting db ... done
Fetching gem metadata from https://rubygems.org/
Fetching gem metadata from https://rubygems.org/..........
...
Fetching mysql2 0.5.3
Installing mysql2 0.5.3 with native extensions
$ docker-compose logs app
app |Could not find mysql2-0.5.3 in any of the sources
app | Run `bundle install` to install missing gems.
パスを指定
RUN bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include"
gem一覧の取得
- bundle list:あるプロジェクトがbundlerによって管理されている場合に、そこで使用されているgemを一覧表示するコマンド
- gem list:グローバルにインストールされたgemを一覧表示するコマンド
- ※bundle install --path vendor/bundleなどでインストールされたgemについては表示されない
bundle install時に--path vendor/bundleを付けるべきか
rubyのパス
- RUBY EXECUTABLE:Ruby実行時のパス
- GEM PATHS:gemのパス
$ docker-compose run app gem environment
Starting db ... done
RubyGems Environment:
- RUBYGEMS VERSION: 3.2.22
- RUBY VERSION: 3.0.2 (2021-07-07 patchlevel 107) [x86_64-linux]
- INSTALLATION DIRECTORY: /usr/local/bundle
- USER INSTALLATION DIRECTORY: /root/.local/share/gem/ruby/3.0.0
- RUBY EXECUTABLE: /usr/local/bin/ruby
- GIT EXECUTABLE: /usr/bin/git
- EXECUTABLE DIRECTORY: /usr/local/bundle/bin
- SPEC CACHE DIRECTORY: /root/.local/share/gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /usr/local/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /usr/local/bundle
- /root/.local/share/gem/ruby/3.0.0
- /usr/local/lib/ruby/gems/3.0.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- "install" => "--no-document"
- "update" => "--no-document"
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /usr/local/bundle/bin
- /usr/local/sbin
- /usr/local/bin
- /usr/sbin
- /usr/bin
- /sbin
- /bin
Gemfile.lockはコミットすべき
それぞれの環境で違うバージョンのgemを入れた時、将来それがきっかけでバグが発生した時に対処が困難になるからです。
Ruby on Rails で Web API のパラメータをバリデーションする
- moduleとclassの使い分け
- module:インスタンスを作れないがメソッドを格納できる
- class:インスタンスを作れる
- クラス定義をモジュール構文で囲うことで、名前空間を分けることが出来る
- モジュールの include と extend
クラスとメソッドのライブラリとの衝突を避ける
設計・実装
- パラメータのバリデーションどうするか?
- モデルへのバリデーション
- コントローラの
RSpec
RSpec
テスト対象の振る舞いを列挙する
- describe:テストの対象
- context:特定の条件が何か
- example,it:アウトプットが何か
-
before:
-
before(:all):context/describe ブロックが始まる時に一度だけ実行される
-
before(:each):各スペック内のitの前に実行される
- modelsのconcerns:共通部分をまとめる
- https://lanlib.com/2021/04/04/rails-concernの使い方/
- module作成してクラス内でincludeして読み込む
- 単一責任のクラスを作る:複数の役割を持たせない
- 共通処理はモジュールにする
- returnはできるだけ書かない
- https://github.com/kure-kosen/QnA-Issues/issues/4
- 早期returnで利用する程度
- return書かないのに違和感ありましたが慣れたい
- moduleのメリット
- メソッドや定数を一箇所にまとめて整理しておくことができる。
- クラスで読み込むこと(Mix-in)ができ、多重継承が実現できる。
- 名前空間を分けて、メソッド名の重複を防げる。
- https://26gram.com/ruby-module
- 特異メソッド:オブジェクトに対して直接固有のメソッドを定義することができる
- moduleのselfって何?
- モジュールの外からメソッドを直接呼び出すことができるようになる
- 変数
- インスタンス変数(@で始まる変数)
- クラスから生成されたオブジェクトがインスタンス
- initializeメソッドとオブジェクトのインスタンスメソッドのみアクセス可
- インスタンス変数を外から呼ぶ場合getter/setter要(attr_accessorを利用)
- インスタンス変数はprivate扱いとなる
- クラス変数(@@で始まる変数)
- クラスの特異メソッド、インスタンスメソッドなどから参照/代入ができる
- サブクラスから参照/代入が可能
- インスタンス変数(@で始まる変数)
- 定数:https://moonstruckdrops.github.io/blog/2014/03/23/rails-consts/
- freezeつける(rubocopで自動整形できるので自分で書かなくてもいい)
- アノテーション
- TODO:後日追加が必要な、不足の機能
- FIXME:修正の必要な箇所
- OPTIMIZE:パフォーマンス低下の原因となる箇所
- HACK:リファクタリングの必要なマズいコード
- REVIEW:意図したとおりに動くかどうかチェックが必要
- rspec
- allow_any_instance_of:オブジェクトのローカル変数など、簡単にモックにできない場所に利用
- 非推奨ではある
- https://dev.classmethod.jp/articles/rspec-recipe
- be_truthy:
- Rubyの真偽値の評価:false または nil であれば偽、それ以外は全て真
- https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5
- rspecスタイルガイド:https://github.com/willnet/rspec-style-guide
- Rakeタスク
- 薄いグルーコードにする(具体的な処理は持たず呼び出すだけ)
- 細かいロジックを別のクラスやモジュールに記述し、Rakeタスク自体は、CLIとのI/Fであったり、実行フローの管理の責務のみをもたせる
- https://qiita.com/aeroastro/items/c97bd26ce8b8818b6bed
- rakeタスクの呼び出し
- Rake::Task['with:args'].invoke("pizza")
- 複数回タスクを呼び出したい場合は「Rake::Task#reenable」の実行要
- environmentメソッド
- タスクの処理をアプリケーション環境に依存させた上で実行する
- Rails上に設定したモデルの情報を取り扱うことが可能となる
- モック
- described_class:テストコードを書くモデルを直接対象としている
- なるべくsubjectは使わない方がいい
- https://blog.jnito.com/entry/2021/10/09/105651
- subjectの使いどころ = メソッドの戻り値をテストするケース
- subjectが向いていないケース = メソッドの副作用をテストするケース
- 良いインタフェースとは
- 正しく使用する方が操作ミスをするより簡単
- 誤った使い方をすることが困難
- コード中であり得ない事象が発生した場合、どのような場合でも速やかに停止させるべき
- 利用側の責任である場合は表明(assert)を使う
- 「開発時に実装のミスをしないように」、「開発者を支援するため」
- 暗黙の前提を明示し、バグをあぶりだす表明プログラミング
- 起こるはずがないと思っていることがあれば、チェックする→表明する