作業中に「お使いの起動ディスクは一杯です」というダイアログが表示された。
この3つのコマンド走らせるだけで、30Gほど空きスペースを確保できた。
ちょっと放置し過ぎか
作業中に「お使いの起動ディスクは一杯です」というダイアログが表示された。
この3つのコマンド走らせるだけで、30Gほど空きスペースを確保できた。
ちょっと放置し過ぎか
PostgreSQL には ? という演算子があって、JSONB型に対して文字列の検索が行える。
-- true を返す SELECT '["a", "b", "c"]' ? 'a'; -- 管理者検索 SELECT * FROM users WHERE roles ? 'ADMIN';といった使い方ができる。
ところが、例えば DOMA のようなフレームワークやバックエンドでJDBCを使っているツールなどではエラーとなる。
これを避けるためには ? をエスケープしてやればよくて、
-- true を返す SELECT '["a", "b", "c"]' ?? 'a'; -- 管理者検索 SELECT * FROM users WHERE roles ?? 'ADMIN';としてやればよい。
tail -f pinzo.log: Deviseの有効期限設定をテストする で書いた有効期限検証のコードで不思議な事が起こった。Macでは正常にパスするのだが、Amazon Linux上ではパスしない。
ミニマムなコードで示すとこんな感じ
で、こんなデバッグコードを仕込んで実行してみた
Macで実行するとこんな感じ
[test-code][sent_at] to_s: 2016-02-01 23:51:31 +0900, to_i: 1454338291, usec: 197593, subsec: 197593/1000000 [test-code][added] to_s: 2016-02-11 23:51:31 +0900, to_i: 1456930291, usec: 197593, subsec: 197593/1000000 [devise][now] to_s: 2016-02-11 23:51:31 +0900, to_i: 1456930291, usec: 197593, subsec: 197593/1000000 [devise][sent_at] to_s: 2016-02-01 23:51:31 +0900, to_i: 1454338291, usec: 197593, subsec: 197593/1000000 [devise][added] to_s: 2016-02-11 23:51:31 +0900, to_i: 1456930291, usec: 197593, subsec: 197593/1000000 [devise] now > added: false [devise] now.subsec > added.subsec: false
Amazon Linuxで実行するとこんな感じ
[test-code][sent_at] to_s: 2016-02-01 23:53:20 +0900, to_i: 1454338400, usec: 369658, subsec: 369658841/1000000000 [test-code][added] to_s: 2016-02-11 23:53:20 +0900, to_i: 1456930400, usec: 369658, subsec: 369658841/1000000000 [devise][now] to_s: 2016-02-11 23:53:20 +0900, to_i: 1456930400, usec: 369658, subsec: 369658841/1000000000 [devise][sent_at] to_s: 2016-02-01 23:53:20 +0900, to_i: 1454338400, usec: 369658, subsec: 184829/500000 [devise][added] to_s: 2016-02-11 23:53:20 +0900, to_i: 1456930400, usec: 369658, subsec: 184829/500000 [devise] now > added: true [devise] now.subsec > added.subsec: true
usecまでは同じなのだが、subsec をみると Amazon Linux では、桁落ちが発生している。
ためしにそれぞれで Time.now.subsec としてみる。
# mac $ ruby -e 'puts Time.now.subsec' 276987/1000000 # Amazon Linux $ ruby -e 'puts Time.now.subsec' 704462593/1000000000
つまりこういうことが起こっている
Time#subsec が返す精度が異なるcreate で返すのは、コードで指定された値を格納したオブジェクトであり、DBに登録後取得したものではないので confirmation_sent_at はそのままの精度である。つまり、スタブで突っ込んでいるのは元の精度Time#subsecの精度がsqliteの精度と同じだったため桁落ちが発生せず正常に動作するこれを避けるためには、スタブに突っ込む値をDBから取得したものにすれば良さそうだ。たとえばこんな感じ
ちなみに Mac でも、桁落ちを引き起こすことは可能で、こんな感じで usec を超えた範囲を指定すれば桁落ちさせられる。
あー疲れた、腹減った
管理者とユーザーでのログイン機能が存在し、別モデルで管理したい場合、Devise を使うとscoped_viewsをtrueにすれば簡単に実装できる。(参考:Ruby - Railsでdeviseひとつで複数モデルを管理しよう - Qiita)
しかし、デフォルトの場合 Devise のログアウトは全てのスコープでログアウトしてしまう。つまり管理者とユーザーでログインしていた場合、管理者としてログアウトすると同時にユーザーとしてもログアウトしてしまう
これを防ぎたい場合、config/initializers/devise.rb にて config.sign_out_all_scopes = false としてやればよい。
初期状態ではこの設定はコメントアウトされているので、コメントアウトを外しfalseに設定するだけで、スコープごとのサインアウトが実装できる。
テストコード込みのサンプルコードはこんな感じ。
JavaScript で new Date(text) や Date.parse(text) した時に読み込める形で TimeWithZone の値を出力したい。
そのまま to_s すると 2015-01-18 12:34:56 +0900 となるが、これでは Chrome でしか読み込めない。
2015/01/18 12:34:56 +0900 という形式ならば Chrome, IE, Firefox で読み込むことができた
もしくは、せっかく to_json メソッドがあるんだからこれを利用すると安心。しかし余計なダブルクォートは取り除く必要がある。あと、人が見た時は先述のやり方のほうがぱっと見で理解しやすいと思う
to_json 経由だとミリ秒まで含まれているから完全に等価ではないけど、そこらへんは要件しだいということで
まあ、色々やり方はあるので好きなやり方を使えばいいと思う。
Qiita::Markdownはシンタックスハイライトに Pygments を使用しているのでインストールしておく(sudo pip install pygments)
そして、おもむろに Gemfile に gem 'qiita-markdown' として bundle install してみる。
Installing charlock_holmes 0.7.3 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
/usr/bin/ruby2.2 -r ./siteconf20160110-30152-1igbivj.rb extconf.rb
checking for main() in -licui18n... no
which: no brew in (/home/ec2-user/bin:/home/ec2-user/.rbenv/bin:/home/ec2-user/bin:/home/ec2-user/.rbenv/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/opt/aws/bin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/opt/aws/bin)
checking for main() in -licui18n... no
***************************************************************************************
*********** icu required (brew install icu4c or apt-get install libicu-dev) ***********
***************************************************************************************
*** 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}/lib64
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/bin/$(RUBY_BASE_NAME)2.2
--with-icu-dir
--without-icu-dir
--with-icu-include
--without-icu-include=${icu-dir}/include
--with-icu-lib
--without-icu-lib=${icu-dir}/lib64
--with-icui18nlib
--without-icui18nlib
--with-icui18nlib
--without-icui18nlib
extconf failed, exit code 1
Gem files will remain installed in /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/gems/charlock_holmes-0.7.3 for inspection.
Results logged to /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/extensions/x86_64-linux/2.2/charlock_holmes-0.7.3/gem_make.out
Installing rugged 0.24.0b11 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
/usr/bin/ruby2.2 -r ./siteconf20160110-30152-1y0cp2j.rb extconf.rb
checking for gmake... yes
checking for cmake... no
ERROR: CMake is required to build Rugged.
*** 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}/lib64
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/bin/$(RUBY_BASE_NAME)2.2
--use-system-libraries
extconf failed, exit code 1
Gem files will remain installed in /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/gems/rugged-0.24.0b11 for inspection.
Results logged to /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/extensions/x86_64-linux/2.2/rugged-0.24.0b11/gem_make.out
とまあ、2つのエラーが出た。Amazon Linuxは yum だからlibicu-dev じゃなくて libicu-devel にすればOKかな?
sudo yum install -y libicu-devel cmake して bundle install したらインストールは成功したようだ
インストールは成功したのでこんなコードを書いて使えば Markdown に変換された。ばっちりばっちり
module ApplicationHelper
def markdown(source)
Qiita::Markdown::Processor.new.call(source)[:output].to_s.html_safe
end
end
変換はばっちりだがシンタックスハイライトがされていない。いや、正確にはスタイルシートがない。
richleland/pygments-css あたりでお好みのものを利用させてもらおう
シンタックスハイライトも完了した。次は絵文字である。
gemoji | RubyGems.org | your community gem host がインストールされているはずなので、Rakefile に下記の行を加える。
load 'tasks/emoji.rake'あとは
bundle exec rake emoji を実行すれば /public/images/emoji 以下に画像はファイルが配置される。bundle と rake で導入できるので /public/images/emoji は .gitignore に加えておいてもいいかもしれない。大量に画像ファイルをリポジトリに登録したくないもんね
みんな大好き Object#tap
でもこんなソースはあまり書きたくない。
foo.bar.baz.tap do |baz| do_something(baz) if baz end
tap_if とかあれば便利じゃない?
foo.bar.baz.tap_if do |baz| do_something(baz) end # もしくは foo.bar.tap_if(:baz) do |baz| do_something(baz) end
似たようなことを考える人はいるものですでにある。→ tap-if | RubyGems.org | your community gem host
そして Rails やる上では try で事足りることがわかった。ブロック取れるのか。
foo.bar.baz.try do |baz| do_something(baz) end # もしくは foo.bar.try(:baz) do |baz| do_something(baz) end結論:
Object#try サイコー
ActiveSupport::TestCase は minitest を使っていて、minitest/mock には定数をスタブ化する機能はない。assert_difference がありますね。test 'ユーザーが確認済みになること' do assert_not user.confirmed? # ここに承認処理 assert user.confirm? endそれならば、こんなメソッドを test_helper あたりに定義しておいて
test 'ユーザーが確認済みになること' do
assert_change 'user.confirmed?' do
# ここに承認処理
end
end
# 実際の値を気にしなくていいならこんな使い方も
test '保存したら updated_at が更新される' do
assert_change 'user.updated_at' do
user.save
end
end
と書くとちょっとスッキリしますね。コードはほぼほぼ assert_difference のパクリです。expression の指定方法は必要になったら広げる感じでいいかな。
dragoverを補足してキャンセルしておかないとdropイベントを補足してくれなかったのにハマった