sorceryの細かい設定
sorceryを触っていて、気になったことがあったので記事として残す。
背景
railsのgem sorceryをユーザー認証として採用した。
sorceryのreset password機能も組み込んだが、間髪入れずに何回か連続で実行するも
1回目のメールしか届かなかった。
やりたいこと
メールの送信間隔を自由に設定したい。
方法
ドキュメントに従って、以下コマンドを入力すると
config/initializersにsorcery.rbが生成される。
rails g sorcery:install
sorcery.rbを細かく見ると、以下のような記述がある。
# Hammering protection: how long in seconds to wait before allowing another email to be sent. # Default: `5 * 60` # # user.reset_password_time_between_emails =
デフォルトでは、5 * 60 の300秒(5分)となっているとのこと。
コメントアウトを外し、ここの数字を設定してあげる。
# Hammering protection: how long in seconds to wait before allowing another email to be sent. # Default: `5 * 60` # user.reset_password_time_between_emails = 5
以上のようにすると、5秒間隔でメールが送れるようになる。
メールが届かないのは意外と不安になるので、この設定はそこそこ大事かもしれない。
備考
また、よくあるリセットパスワードURLの有効期間もsorcery.rbで自由に設定できる。
以下記述を見つける。
# How many seconds before the reset request expires. nil for never expires. # Default: `nil` # # user.reset_password_expiration_period =
コメント部分を和訳すると、
リセットパスワードのURL生成した後、何秒で無効化されるか。 nilの場合、一生有効のまま。
とのこと。
従って、この部分を
user.reset_password_expiration_period = 600
のようにしてあげると、10分間で切れるURLを生成することができる。
Cannot allocate memoryエラー
問題
AWS EC2上で無料枠でインスタンスを動かしていたところ以下内容のエラーに遭遇。
何を入力しても以下エラーしか出ないようになってしまった。
-bash: fork: Cannot allocate memory
調べたところ、「インスタンスの容量が足りないよ」という意味らしい。
条件
AWS EC2 + rails + nginx + unicorn
対処
仮想メモリというものがLINUXに備わっているらしく、それを追加してあげる。
まず、一旦exitして、もう一回ログインする。
ログインできたら、スワップファイルを確保するコマンドを入力。
※ sudoつけないとpermission errorが出てしまった。
sudo fallocate -l 512M /swapfile
スワップファイルのアクセス権を変更。
sudo chmod 600 /swapfile
次に、仮想メモリとして、使うファイルを指定
[user@ip-10-0-0-196 ~]$ sudo mkswap /swapfile スワップ空間バージョン 1 を設定します。サイズ = 512 MiB (536866816 バイト) ラベルはありません, UUID=26d53dd6-cb4d-4869-9334-102f63fde902
仮想メモリを有効化して完了。
sudo swapon /swapfile
仮想メモリの大きさは、自由に変更出来るようなので
状況に合わせて数値を変更してください。
therubyracerがinstallできない
はじめに・環境
このエラーについては様々な記事を読んだが、どれも自分に当てはまらないものが多かった。 libv8などのversionによっても解決方法が変わるため、あくまで参考程度に読んでいただくと良いかもしれません。
対象 | Version |
---|---|
OS | macOS Catalina version10.15.7 |
libv8 | 3.16.14.19 |
therubyracer | 0.12.3 |
rails | 5.2.3 |
ruby | 2.6.5 |
bundler | 2.0.2 |
therubyracerとは
therubyracer
は、Javascriptの実行エンジンであるv8をrubyから叩くために導入するgem。
libv8は以下の様に、therubyracer
との依存関係があり、インストールされるようになっている。
Gemfile.lock
therubyracer (0.12.3) libv8 (~> 3.16.14.15) ref
経緯
まず、bundle install --vendor/bundle
を実行した際に以下エラーが出現。
Fetching therubyracer 0.12.3 Installing therubyracer 0.12.3 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension. current directory: /Users/myname/Desktop/runteq/advanced/workdir/vendor/bundle/ruby/2.6.0/gems/therubyracer-0.12.3/ext/v8 /Users/myname/.rbenv/versions/2.6.5/bin/ruby -I /Users/myname/.rbenv/versions/2.6.5/lib/ruby/2.6.0 -r ./siteconf20210123-53283-11tly30.rb extconf.rb --with-v8-dir\=/usr/local/Cellar/v8/8.8.278.14 checking for -lpthread... yes checking for -lobjc... yes checking for v8.h... no *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --without-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/Users/hamorotaiga/.rbenv/versions/2.6.5/bin/$(RUBY_BASE_NAME) --with-pthreadlib --without-pthreadlib --with-objclib --without-objclib --enable-debug --disable-debug --with-v8-dir --with-v8-include --without-v8-include=${v8-dir}/include --with-v8-lib --without-v8-lib=${v8-dir}/lib /Users/myname/Desktop/workdir/vendor/bundle/ruby/2.6.0/gems/libv8-3.16.14.19/ext/libv8/location.rb:50:in `configure': By using --with-system-v8, you have chosen to use the version (Libv8::Location::System::NotFoundError) of V8 found on your system and *not* the one that is bundled with the libv8 rubygem. However, your system version of v8 could not be located. Please make sure your system version of v8 that is compatible with 3.16.14.19 installed. You may need to use the --with-v8-dir option if it is installed in a non-standard location from /Users/myname/Desktop/workdir/vendor/bundle/ruby/2.6.0/gems/libv8-3.16.14.19/lib/libv8.rb:7:in `configure_makefile' from extconf.rb:32:in `<main>' To see why this extension failed to compile, please check the mkmf.log which can be found here: /Users/myname/workdir/vendor/bundle/ruby/2.6.0/extensions/x86_64-darwin-19/2.6.0/therubyracer-0.12.3/mkmf.log extconf failed, exit code 1 Gem files will remain installed in /Users/myname/workdir/vendor/bundle/ruby/2.6.0/gems/therubyracer-0.12.3 for inspection. Results logged to /Users/myname/workdir/vendor/bundle/ruby/2.6.0/extensions/x86_64-darwin-19/2.6.0/therubyracer-0.12.3/gem_make.out An error occurred while installing therubyracer (0.12.3), and Bundler cannot continue. Make sure that `gem install therubyracer -v '0.12.3' --source 'https://rubygems.org/'` succeeds before bundling. In Gemfile: therubyracer
最後らへんに、
gem install therubyracer -v '0.12.3' --source 'https://rubygems.org/'
とあり、実行してもこんな感じのエラーが出る。
checking for -lpthread... yes checking for -lobjc... yes *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. ~中略~ extconf failed, exit code 1 ~後略~
解決策
① brew list
を実行し、v8@3.15がインストールされているのを確認
autoconf ghostscript imagemagick liblqr node pkg-config shared-mime-info yarn composer glib jpeg libomp oniguruma postgresql sqlite docbook gnu-getopt jq libpng openexr protobuf v8@3.15 docbook-xsl heroku krb5 libtiff openjpeg python@3.8 webp freetype heroku-node libde265 libtool openssl@1.1 rbenv x265 gdbm icu4c libffi little-cms2 pcre readline xmlto gettext ilmbase libheif mysql phpmyadmin ruby-build xz
② brew uninstall v8@3.15
で、v8@3.15を一旦アンインストールする。
③ brew install v8@3.15
で、再びインストールする。
④ libv8のパスの設定をする
bundle config --local build.libv8 --with-system-v8
⑤ therubyracerのパスの設定をする
myname@mbp workdir % bundle config --local build.therubyracer --with-v8-dir=$(brew --prefix v8-315) You are replacing the current local value of build.therubyracer, which is currently "--with-v8-dir=/usr/local/Cellar/v8/8.8.278.14"
which is currently のあとが nil
になってしまう場合は失敗している可能性がある。
--with-v8-dir=$(brew --prefix v8-315)
このフラグは、brew install
した際に格納される場所を返している。
⑥ これでbundle install --vendor/bundle
を実行
以上、手順で解決。
bundle install時に、mysql2のインストールが失敗する
bundle installをしていて、以下のエラーに遭遇した。
Gem::Ext::BuildError: ERROR: Failed to build gem native extension. current directory: /Desktop/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.3/ext/mysql2 /Users/.rbenv/versions/2.6.5/bin/ruby -I /Users/hamorotaiga/.rbenv/versions/2.6.5/lib/ruby/2.6.0 -r ./siteconf20210123-38999-1g3nre5.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.21_1/lib ----- creating Makefile current directory: /Users/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.3/ext/mysql2 make "DESTDIR=" clean current directory: /Users/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.3/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/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.3 for inspection. Results logged to /Users/vendor/bundle/ruby/2.6.0/extensions/x86_64-darwin-19/2.6.0/mysql2-0.5.3/gem_make.out An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling. In Gemfile: mysql2
エラー文を読んでいくと、以下がどうやらヒントらしい。
ld: library not found for -lssl
このエラー文は「mysql2 gemはlibssl.dylibをライブラリ検索範囲内で探せ」という意味。 どうやら、検索範囲内で探したが見つからなかった様子。
では、検索範囲が間違っている可能性を考え、どこを探しに行ったのか確認すると 以下が検索範囲だとわかる。
Setting libpath to /usr/local/Cellar/mysql/8.0.21_1/lib
ただ、そこに見に行ってもlibssl.dylibが見つからない。
@mbp workingdir % ls -l /usr/local/Cellar/mysql/8.0.21_1/lib total 48280 -rw-r--r-- 1 hamorotaiga staff 7284896 Oct 18 11:05 libmysqlclient.21.dylib -r--r--r-- 1 hamorotaiga staff 8097728 Jun 17 2020 libmysqlclient.a lrwxr-xr-x 1 hamorotaiga staff 23 Jun 17 2020 libmysqlclient.dylib -> libmysqlclient.21.dylib -r--r--r-- 1 hamorotaiga staff 772188 Oct 18 11:05 libmysqlharness.1.dylib -r--r--r-- 1 hamorotaiga staff 8184928 Oct 18 11:05 libmysqlrouter.1.dylib -r--r--r-- 1 hamorotaiga staff 249564 Oct 18 11:05 libmysqlrouter_http.1.dylib -r--r--r-- 1 hamorotaiga staff 85764 Oct 18 11:05 libmysqlrouter_http_auth_backend.1.dylib -r--r--r-- 1 hamorotaiga staff 24084 Oct 18 11:05 libmysqlrouter_http_auth_realm.1.dylib -r--r--r-- 1 hamorotaiga staff 9760 Jun 17 2020 libmysqlservices.a drwxr-xr-x 14 hamorotaiga staff 448 Jun 17 2020 mysqlrouter drwxr-xr-x 3 hamorotaiga staff 96 Oct 18 11:05 pkgconfig drwxr-xr-x 106 hamorotaiga staff 3392 Jun 17 2020 plugin
解決策
正しい検索範囲を伝える。
つまり、以下を実行。 bundle install時に以下オプションでpathを指定する。
- --with-cppflags
- --with-ldflags
brew info openssl@1.1 と入力しpathを確認する。
~前略~ For compilers to find openssl@1.1 you may need to set: export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" ~後略~
あとは、フラグをつけて、以下のように実行。
gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl@1.1/include --with-ldflags=-L/usr/local/opt/openssl@1.1/lib
これで無事解決しましたとさ。
Rubyメソッド集【備忘録】
チェリー本を読んでいたが、何も覚えていなかったので、アウトプットする。 www.amazon.co.jp
公式ドキュメントを読めば全て書いてあるので、全て知りたい人はそちらまで。
公式ドキュメント_Ruby 2.7.0 リファレンスマニュアル
docs.ruby-lang.org
組み込みライブラリdocs.ruby-lang.org
組み込みライブラリは Ruby 本体に組み込まれているライブラリのこと。このライブラリに含まれるクラスやモジュールは、 require を書かなくても使うことができる。
文字列編
to_s 文字列にする
to_f 整数から小数にする
to_i 整数にする
paizaをやっていると、デフォルトは以下のようになっている。
input_line = gets puts input_line
getsメソッド(読み方は「ゲッツ」ではなく、「ゲットエス」get stringの略)を使っているため、変数input_lineには文字列が入る。
整数同士の割り算は整数になり、小数点以下は切り捨てられる。
小数点以下の値が必要な場合は、どちらかの値に小数点の.0を付けます。
数値の切り捨て・切り上げ・四捨五入については以下の記事参照。
Rubyで数値の切り捨て・切り上げ・四捨五入する
sprintfメソッド 指定されたフォーマットの文字列を作成する
sprintf('%0.3f', 1.2) # => "1.200"
%0.3f:小数第3位まで数字を表示させるフォーマット文字列
配列と繰り返し処理
puts [1,2,3].size 3 => nil
sumメソッド
合計値を算出する。
puts [1,2,3].sum 6 => nil
uniqメソッド
配列から重複した要素を取り除いた新しい配列を返す。
p [1,2,2,3,5,5,6].uniq [1, 2, 3, 5, 6] => [1, 2, 3, 5, 6]
sampleメソッド
p [1,2,3].sample 3 => 3
shuffleメソッド
p [1,2,3].shuffle [1, 3, 2] => [1, 3, 2]
sortメソッド
昇順に並び替える
p [1,3,2].sort [1, 2, 3] => [1, 2, 3]
降順にしたい場合は、reverseをつける
p [1,3,2].sort.reverse [3, 2, 1] => [3, 2, 1]
joinメソッド
p [1,2,3,4].join "1234" => "1234" p [1,2,3,4].join("/") "1/2/3/4" => "1/2/3/4"
splitメソッド
スペース区切りになっている文字列を配列にして返す。
p ("a b c d e").split ["a", "b", "c", "d", "e"] => ["a", "b", "c", "d", "e"]
引数を指定すると、スペース以外の文字にも対応できる。
p ("abcde").split("c") ["ab", "de"] => ["ab", "de"]
deleted_at()
配列内の特定の1にある要素を削除したい時
a = [1,2,3] a.deleted_at(2) #=> 3 a => [1,2]
divmodメソッド
割り算の商と余りを配列として返す
14.divmod(3) => [4,2]
deleteメソッド
配列に指定した値に完全一致する要素を削除する
a = [1,2,3,1,2,3] a.delete(2) a => [1,3,1,3]
delete_ifメソッド
条件をみたした要素だけ削除したい時
a = [0, 1, 2, 3, 4, 5] a.delete_if{|x| x % 2 == 0} p a #=> [1, 3, 5]
ブロックを使う配列のメソッド
numbers = [1,2,3,4,5] new_numbers = numbers.map { |n| n * 10 } new_numbers => [10,20,30,40,50]
空の配列を用意して、他の配列をループ処理した結果を空の配列に詰め込むような処理に適している
select/find_all
各要素に対して、ブロックを評価し、その戻り値が真の要素を集めた配列を返す
numbers = [1,2,3,4,5,6] even_numbers = numbers.select { |n| n.even? } even_numbers => [2,4,6]
reject
selectの反対で、真にならなかった要素を集めた配列を返す
numbers = [1,2,3,4,5,6] odd_numbers = numbers.reject { |n| n.even? } odd_numbers => [1,3,5]
find/detect
ブロックの戻り値が真になった最初の要素を返す
numbers = [1,2,3,4,5,6] even_number = numbers.find { |n| n.even? } even_number => 2
inject/reduce
たたみ込み演算を行うメソッド
numbers = [1,2,3,4] sum = numbers.inject(0) { |result, n| result + n } sum => 10
ブロックの第1引数は初回のみinjectメソッドの引数が入ります。この場合は0。
2回目以降は前回のブロックの戻り値が入る。
injectでフィボナッチ数列を考える
(0..10).inject([1,1]) { |fib, n| fib << fib[n] + fib[n+1] } #=> [1, 1, 3, 3, 7, 7, 15, 15, 31, 31, 63, 63, 127]
1回目:fib = [1,1], n = 0。fib[n] = 1, fib[n+1] = 1。fibに2が追加される
2回目:fib = [1,1,2], n = 1。fib[n] = 1, fib[n+1] = 2。fibに3が追加される
3回目:fib = [1,1,2,3], n = 2。fib[n] = 2, fib[n+1] = 3。fibに5が追加される
以下条件下のみ、&:メソッド名という書き方が出来る。
①ブロック引数が1つだけ
②ブロックの中で呼び出すメソッドには引数がない
③ブロックの中では、ブロック引数に対してメソッドを1回呼び出す以外の処理がない。
範囲(Range)
配列や文字列の一部を抜き出す
a = [1,2,3,4,5] a[1..3] => [2,3,4] a[1...3] => [2,3] a = 'abcdef' a[1..3] => "bcd"
n以上m以下、n以上m未満の判定をする
def liquid?(temperature) (0...100).include?(temperature) end
to_a
値が連続する配列を作る
(1..5).to_a #=> [1,2,3,4,5] (1...5).to_a #=> [1,2,3,4] ('a'..'c').to_a => ["a", "b", "c"]
スプラット展開
[*1..5] #=> [1,2,3,4,5] [*'a'..'c'] #=> ["a", "b", "c"]
繰り返し処理を行う
範囲オブジェクトに対して、直接eachメソッドを呼び出すことが可能
sum = 0 (1..4).each { |n| sum += n } sum #=> 10
stepメソッドを使うと、値を増やす間隔を指定できる
numbers = [] (1..10).step(2) {|n| numbers << n } #=> (1..10) numbers #=> [1,3,5,7,9]
nからmまで、数値をx個ずつ増やしながら処理を行う
開始値.step(上限値, 1度に増減する大きさ)
numbers = [] 1.step(10, 2) { |n| numbers << n } #=> 1 numbers #=> [1,3,5,7,9]
times
配列を使わず、単純にn回処理したい場合
sum = 0 5.times { |n| sum += n } sum #=> 10
upto
nからmまで数値を1つずつ増やしながら何か処理をしたい場合
a = [] 10.upto(14) { |n| a << n } a #=> [10,11,12,13,14] a = [] 'a'.upto('e') { |n| a << n } a #=> ["a", "b", "c", "d", "e"]
downto
逆に減らしたい場合
a = [] 14.downto(10) {|n| a << n }