bundleでmysqlをインストールできない問題

問題

$ 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 12.3.1
Using concurrent-ruby 1.0.5
Using i18n 1.1.0
Using minitest 5.11.3
Using thread_safe 0.3.6
Using tzinfo 1.2.5
Using activesupport 5.1.6
Using builder 3.2.3
Using erubi 1.7.1
Using mini_portile2 2.3.0
Using nokogiri 1.8.4
Using rails-dom-testing 2.0.3
Using crass 1.0.4
Using loofah 2.2.2
Using rails-html-sanitizer 1.0.4
Using actionview 5.1.6
Using rack 2.0.5
Using rack-test 1.1.0
Using actionpack 5.1.6
Using nio4r 2.3.1
Using websocket-extensions 0.1.3
Using websocket-driver 0.6.5
Using actioncable 5.1.6
Using globalid 0.4.1
Using activejob 5.1.6
Using mini_mime 1.0.1
Using mail 2.7.0
Using actionmailer 5.1.6
Using activemodel 5.1.6
Using arel 8.0.0
Using activerecord 5.1.6
Using public_suffix 3.0.3
Using addressable 2.5.2
Using bindex 0.5.0
Using bundler 1.16.4
Using byebug 10.0.2
Using xpath 3.1.0
Using capybara 2.18.0
Using ffi 1.9.25
Using childprocess 0.9.0
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using coffee-script 2.4.1
Using method_source 0.9.0
Using thor 0.20.0
Using railties 5.1.6
Using coffee-rails 4.2.2
Using multi_json 1.13.1
Using jbuilder 2.7.0
Using rb-fsevent 0.10.3
Using rb-inotify 0.9.10
Using ruby_dep 1.5.0
Using listen 3.1.5
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/user/Development/zeroone-admin/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
/Users/user/.rbenv/versions/2.5.1/bin/ruby -r ./siteconf20190409-1971-1uhtf43.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... no
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/Cellar/mysql/8.0.15/lib
-----
creating Makefile

current directory: /Users/user/Development/zeroone-admin/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/user
/Development/zeroone-admin/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/user/Development/zeroone-admin/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/user/Development/zeroone-admin/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-17/2.5.0-static/mysql2-0.5.2/gem_make.out

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2


解決

$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include"
$ bundle install

参考:RailsプロジェクトでMySQLがbundle installできなかった - Qiita



問題

docker-composeでrailsアプリケーションを起動しようとしたら、

bundler: failed to load command: rails (/usr/local/bundle/bin/rails)
Bundler::GemNotFound: Could not find mysql2-0.5.2 in any of the sources

mysql2が見つからないらしい

確認してみても、

$ gem list

...
multi_json (1.13.1)
multipart-post (2.0.0)
mustermann (1.0.3)
nenv (0.3.0)
net-telnet (0.1.1)
...

やっぱりmysqlはない

gem installmysqlを入れてみる

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'
Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
        ERROR: Failed to build gem native extension.

    current directory: /Users/user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
/Users/user/.rbenv/versions/2.5.1/bin/ruby -r ./siteconf20190409-1589-65zdj9.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... no
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/Cellar/mysql/8.0.15/lib
-----
creating Makefile

current directory: /Users/user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-17/2.5.0-static/mysql2-0.5.2/gem_make.out

エラーーーーーー


解決

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib


Building native extensions with: '--with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib'
This could take a while...
Successfully installed mysql2-0.5.2
Parsing documentation for mysql2-0.5.2
Installing ri documentation for mysql2-0.5.2
Done installing documentation for mysql2 after 0 seconds
1 gem installed

無事インストールされた

参考:mysql2 gemインストール時のトラブルシュート - Qiita

【勉強まとめ】Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計



3つのプログラミングパラダイム

構造化プログラミング

構造化プログラミングとは、「順次(上から順にプログラムを実行する)」「反復(for文)」「分岐(if文)」の3つの構造を使ってプログラム構築こと。


オブジェクト指向プログラミング

カプセル化

他のプログラムから干渉されないようにすること

継承

同じようなものをまとめて、それを再利用できるようにすること

ポリモーフィズム

訳:多様性
目的に応じて変えられるようにすること


関数型プログラミング

??



設計の原則

SOLID原則

S:単一責任の原則(Single Responsibility Principle)
O:解放閉鎖の原則(Open/Closed Principle)
L:リスコフの置換原則(Liskov Substitution Principle)
I:インタフェース分離の原則(The Interface Segregation Principle)
D:依存性逆転の原則(Dependency Inversion Principle)

単一責任の原則

「1つのクラスに対して1つの役割」
→クラスを変更する理由が2つ以上存在してはならない


解放閉鎖の原則(オープン・クローズドの原則)

「クラスは拡張に対して開いていて、修正に対して閉じていなければならない」
→オープン=拡張が出来る、クローズド=修正する場合はそのクラスだけ修正すればいい


リスコフの置換原則

「基本クラスを使っている場所で基本クラスの代わりにサブクラスを使っても問題なく動かなけらばならない」


インタフェース分離の原則

「クライアントに、クライアントが本来依存しないメソッドへの依存性を強制してはならない」


依存性逆転の原則

「上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも「抽象」に依存すべきである」



コンポーネントの原則

コンポーネント

コンポーネント=デプロイの単位のこと


コンポーネントの凝集性

凝集性

凝集性=集合体の統合性の強さ
凝集性が高い(機能と機能の関わり具合が低い)ほど良いプログラムとされる


再利用・リソース等価の原則

「リリースの単位が再利用の最小単位」
→再利用の単位はリリースの単位と同一であるべきである。コンポーネントを再利用するには、コンポーネントのリリース単位で行う
コンポーネントに含まれるクラスは、すべてが再利用されるか、すべてが再利用できないかのどちらかにすべき
ex.) Javaのクラスを修正した場合、クラス単位ではなくjar単位でリリース・再利用を行うのが理想


閉鎖性共通の原則

「同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめること。変更の理由やタイミングが異なるクラスは、別のコンポーネントに分ける」
コンポーネントを変更する理由が複数あるべきではない。同じ理由、同じタイミングで変更されることが多いクラスは1つのコンポーネントにまとめておくべき。


全再利用の原則

「1つのクラスだけを再利用するということはめったになく、複数のクラスと組み合わせて使われることがほとんどのため、そうしたクラス群は1つのコンポーネントにまとめる」


コンポーネントの結合

非循環依存関係の原則

コンポーネントの依存グラフに循環依存があってはならない」


安定依存の原則

「安定度の高い方向に依存すること」
→安定度の高い=変更がしづらい


安定度・抽象度等価の原則

コンポーネントの抽象度は、その安定度と同程度でなければならない」
→安定度の高いコンポーネントは抽象度も高くあるべき

プロキシ

プロキシとは

プロキシとは、ブラウザに代わってwebサーバーにリクエストするやつ。

ブラウザ -> プロキシ -> webサーバー
ブラウザ <- プロキシ <- webサーバー

なぜわざわざワンクッション挟むのか

  1. 匿名性
    プロキシを経由しないで、webサーバーへアクセスした場合、アクセス先のサーバーにIPアドレスなどの個人的な情報がわかってしまう。
    プロキシを挟むことで、直接サーバーへアクセスしないので、情報の漏洩を防ぐことができる。

  2. キャッシュ機能による高速化
    プロキシにはキャッシュ機能が付いているため、一度アクセスしたページの情報を貯めておくことができる。
    そのため、同じサイトへもう一度アクセスする際には、webサーバーまでいかずに、プロキシが情報を返してくれる。
    これによって、ページの表示速度がはやくなる。

バイナリデータ・シリアライズ・デシリアライズ

バイナリデータ

バイナリデータとは、コンピュータで扱えるデータで、人間が見ても理解できないデータ

シリアライズ

ソフトウェア内部で扱っているデータをそのままDBへ保存したり送受信できるようにすること。

たとえば、配列をDBへ保存する際に、
普通、DBには「フィールド:値」という形式で保存されるため、配列のデータをそのまま保存することはできない。
仮に「array(‘a’, ‘b’, ‘c’)」という値を保存した場合、それはただの文字列でしかない。
しかし、シリアライズすると、配列データを配列データとして保存することができる。

シリアライズ

シリアライズの逆。
シリアライズしたデータを復元すること。

MinioをDocker上で動かす

minioをインストール

docker pull minio/minio:edge
docker run -p 9000:9000 minio/minio:edge server /data

Dockerfile

RUN mkdir -p /tmps3

docker-compose.yaml

  minio:
    image: minio/minio:latest
    ports:
    - "9000:9000"
    volumes:
    - "./tmps3:/export"
    command: server /data
    environment:
      - "{AccessKey}"
      - "{SecretKey}"

Gemfile

gem 'asset_sync'

asset_sync.yaml

defaults: &defaults
  fog_provider: 'AWS'
  aws_access_key_id: '{AccessKey}'
  aws_secret_access_key: '{SecretKey}'
  # To use AWS reduced redundancy storage.
  # aws_reduced_redundancy: true
  fog_directory: "new-bucket" # バケット名を指定

development:
  <<: *defaults
  enabled: false

test:
  <<: *defaults
  enabled: false

staging:
  <<: *defaults
  fog_directory: "staging-hogehoge"

production:
  <<: *defaults
  fog_directory: "production-hogehoge"

development.rb

  # s3 route
  config.action_controller.asset_host = '//localhost:9000/minio/new-bucket/'

dockerを起動

docker-compose up

ローカルからminioにファイルをアップロード

# s3cmdをインストール
brew install s3cmd

# 設定
s3cmd --configure

Access Key  S3のアクセスキー指定
Secret Key  S3のシークレットアクセスキーを指定
Encryption password GPG encryptionを用いる事でデータを暗号化してくれる。(とりあえず空欄でおk)
Path to GPG program [/usr/bin/gpg]  GPGの場所を指定。(とりあえず空欄でおk)
Use HTTPS protocol [No] S3への通信をHTTPSにするか否か
HTTP Proxy server name  Proxyを使う場合はその指定

# s3cmdが使えることを確認
s3cmd ls

# アップロード
s3cmd put --recursive stylesheets/ s3://zeroone-views/assets/stylesheets/