patorashのブログ

方向性はまだない

後輩との1on1で話したことをまとめておく

1on1というか、今後どうしていきたいか等を話し合っている。継続的に話し合っていくので、まぁ1on1になっていくのかなとも思う。

「一人前」を定義する

目標がめちゃくちゃザックリとしていて、「一人前になる」というものなので、まずは一人前の定義を二人で行った。彼の考える一人前を聞き出して、「つまりはこういうことだろうか?」という感じで固めていった。詰まったときには、「Aさんはあなたから見て一人前と思えますか?」と聞き、そこから、どういうところが一人前と思えるのかを聞き出したりしていった。

現状を振り返る

大体一人前の定義が固まったところで、現状を振り返った。地図があっても現在地が分からなければ、その場所には向かえない。

本格的にプロダクトの開発に入ってもらったことはまだないので、知識も経験もまだまだであることはわかるが、まぁそれは当然のことなので、別に落ち込むことではない。

果たしてそれは本当にやりたいことか?

最近はサイトの作成をやってもらっていて、ようやくそれなりに書けるようになってきたので、それは楽しいという話をしていた。なので、フロントエンドに興味があるという話になったのだが、果たしてそれは本当にやりたいことだろうか?他のことをあまり勉強していない状態で、そう言い切っていいものか?という話をした。先日ホットエントリー入りしていた記事を見せて、説明した。

shiro-16.hatenablog.com

また、越境した結果その分野が実はその人が一番楽しいと思える分野かもしれないからです。僕自身はサーバサイド/インフラから始まり一通り終えてサーバサイド/インフラがやっぱり楽しいと感じましたが、どこかでサーバサイド/インフラより面白いと感じるものがあったのならそこに留まっていたと思うし、仕事をするなら楽しいと思える事をやりたいじゃないですか。経験年数が浅い人ほどというのをつけたのは歳を取ると越境する体力みたいなのが徐々になくなってくるのかなぁと思うからです(個人の感想)

この記事についていたコメントのこれも引用して話した。

ledsunさん: 現実の問題は領域の間に落ちている(それ以外は既に解決されている)ので越境したエンジニアは強い。狭い領域で尖っているエンジニアはわかりやすく強い(実際強い)。

Railsがなんとなく書けるだけでは足りない。コードレビューできるようになるには、Rubyらしい書き方や、RESTの理解が必要だし、自信を持ってそれを言えるだけのバックボーンがいる。自信がないと、「動いているからヨシ!」になってしまってレビューできない。データベースの特性やSQL、インデックスのこと等もわかっていないと、ActiveRecordで作ったクエリが遅くても「なんで遅いのかよくわからんけど動いてるからヨシ!」になってしまう。

遅いのは画像やJS,CSSのファイルサイズが最適化されていなかったからとか、読込が非同期になってなかったからとか、もしかしたらそういうことかもしれない。そういうのは一通り色んな領域を経験しないと気づけない。

ふんわりと要望を伝える

まずは色々やってほしくて、その上でやりたいことを考えていこうということにした。

  • T型人材を目指してほしいこと
  • T型人材になるにしても、浅く広くをできるようになるには、アーキテクチャの知識、エンジニアとしての思想、技術のベースとなる考え方を吸収しておかなければならないこと
  • Railsやフロントエンドは業務でやるからある程度は自動的に力がついていくはず
  • 一人前になるためには、Rails + αのαを頑張ろう
  • αは、Web全般の知識、運用の知識、脆弱性対策方法、アルゴリズムや設計手法、他の言語などなど…

じゃあαをどうやっていくか?っていうところが、おススメの本を聞いて、読んで、感想をアウトプットするとか、得た知識を業務に使っていくという話をした。 とはいえ、自分自身としても「最終的にはもっと本を読もう」で終わってしまうのがなんかモヤモヤしていて、もっといい方法やアイデアないもんか?と思いながら話を終えた。

終えたけれど、「車の免許は座学だけでテストで100点とっても免許渡せないでしょ?実際に運転して運転技術も身につけないといけない」という、いい感じの例えを使えたので、そこはわかってもらえてアウトプットする気になってもらえたみたいでよかった。

Rails 5.2.3から5.2.4.3に更新したらActiveStorageでエラー発生した

社内のRailsアプリのバージョンアップを行ってテストを実行したところ、システムテストが通らなくなりました。

ArgumentError: unexpected value at params[:whitelist_headers]

というエラーが出たので、ググったところ、RailsにPRが…。

github.com

これはRails6.0系の話なので、5.2系はどうなるんだ?と思っていたら、関連issueがありました。

github.com

コメントに、

You can fix this in your own app by upgrading the aws-sdk-s3 gem to 1.48.0 or greater.

とありました。

Gemfile.lockを確認したところ、aws-sdk-s3のバージョンが1.43.0だったので、早速更新。

gem 'aws-sdk-s3', '>= 1.48.0'

これで、bundle update aws-sdk-s3を実行後、テストを実行したら、問題なく通りました!😊

余談

railsのアップグレードをしたら、yarnでrails関連のjsライブラリのバージョンアップもしておきましょう。

yarn add activestorage rails-ujs turbolinks

herokuでjemallocのbuildpackの新しいバージョンが出ていた

過去にこのような記事を書いていました。

patorash.hatenablog.com

この記事を見返しながら、他のHerokuアプリケーションにもjemallocのbuildpackを適用しようと思ってたのですが、なんとなくbuildpackのページに移動したところ、メンテナンス停止になっていました😩全然気づいてなかった〜!!

github.com

新しいほうにforkされてるから最新のjemallocを使いたかったらそちらを、と書いてあったので、そちらを使うようにしました。

github.com

こちらにすることで、jemallocのバージョン5.2.1が使えます。以前のは4.2.1だったかと思います。

activerecord-importの削除は難しい

Rails6にしたので、insert_allメソッドが使えるようになったので、意気揚々とgem activerecord-importを削除しようと修正していってたのだけれど、思ったより難しそうだったので、一旦止めることにした。

activerecord-importの削除が難しい理由

recursiveオプションが便利で、それを使っていた

activerecord-importには再起的に関連データをインポートできる仕組みがあって、それを外していくことの影響度が大きくてテストが落ちまくるようになりました…。gemを削除するためだけ調査するには時間がかかりすぎるので棚上げすることにしました。

問題

insert_allメソッドはHashを対象とするので、モデルの配列を渡してもNGでした。そのため、activerecord-importのimportメソッドをinsert_allに変えただけではダメ。また、insert_allには以下のような問題がありました。

  • idにnilが設定されていると落ちる
  • created_at, updated_atが自動的に入らない

解決できるもの

上記の問題は、attributes_without_idメソッドをApplicationRecordに作成することで大体問題なく動いてくれました。

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  # これを定義
  def attributes_without_id
    self.attributes.except('id').tap do |hash|
      hash[:created_at] ||= Time.zone.now
      hash[:updated_at] ||= Time.zone.now
    end
  end
end

これで、activerecord-importのメソッドは以下のように置換できます。

books = FactoryBot.build_list(:book, 100)

# activerecord-importの場合
Book.import(books)

# insert_allの場合
Book.insert_all(books.map(&:attributes_without_id))

# もしくは、attributes_for_listにすれば、モデルのオブジェクトの生成が不要に。
# 新規に使っていくならこちらがベストかな?
books = FactoryBot.attributes_for_list(:book, 100)
Book.insert_all(books)

最後のやつが最も効率よくデータを作られるはず…(試してない)

まとめ

insert_allは速いけれど、関連データがたくさんあるケースだと厳しい…。無理に削除せずに共存していくことにします。

PaperclipがImageMagickのデフォルト設定の影響で動かなくなったのを直した

昨日、Macのセットアップが終わったという話をしました。

patorash.hatenablog.com

そして、Docker立ち上げて作業後にrspecを流したら、全然関係ないところがエラーで落ちるじゃないですか…😰

pryで止めて、@model.errorsを出力してみると…

@details={:report=>[{:error=>"Paperclip::Errors::NotIdentifiedByImageMagickError"}]}, @messages={:report=>["Paperclip::Errors::NotIdentifiedByImageMagickError"]}>

はて、ImageMagickImageMagickはインストールしてるぞ?と思い、バージョンチェック。

root@67a587ce1af1:/app# convert --version Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org Copyright: © 1999-2019 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC Modules OpenMP Delegates (built-in): bzlib djvu fftw fontconfig freetype heic jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib

やっぱりあるじゃないか…。

調査してみると、Paperclipを使っていても落ちるところと落ちないところがあり、PDFを添付しているところだけが落ちていた。

調査開始

Paperclipというキーワードを起点にググってみると、Paperclip.options[:current_path] = '/usr/bin/'にしてみろというのを見かけたりしたので、convertのパスを確認後に設定してみるも、状況は変わらず。

ImageMagickというキーワードを起点に変更し、ググってみたら、以下のページを発見。

yasuhiroki.hatenablog.com

何かしらのヒントがあるのかなと思って読んでみたところ、脆弱性対応のためにpolicy.xmlを使うように変わったらしいことが判明。 以前のDockerイメージでImageMagickの何のバージョンを使っていたかはもうわからないけれど、今の6.9.10-23では、policy.xmlを使ってそう。

上記の記事では、HTTPSのところをコメントアウトしたとあったが、うちで起きてるのはそもそもそういう話じゃないだろうしなぁ…と思いながらも/etc/ImageMagick-6/policy.xmlの中身を見てみた。 すると…

<policymap>
  <!-- 略 -->
  <!-- disable ghostscript format types -->
  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="PS2" />
  <policy domain="coder" rights="none" pattern="PS3" />
  <policy domain="coder" rights="none" pattern="EPS" />
  <policy domain="coder" rights="none" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="XPS" />
</policymap>

disable ghostscript format typesの文字があった👻 そして、pattern="PDF"のrights="none"ということで、権限がなさそう…。

policy.xmlの前半のほうに、書き方が書いてありました。

<!--
  Configure ImageMagick policies.

  Domains include system, delegate, coder, filter, path, or resource.

  Rights include none, read, write, execute and all.  Use | to combine them,
  for example: "read | write" to permit read from, or write to, a path.

  Use a glob expression as a pattern.

  サンプルがズラズラと…
-->

解決!

pattern="PDF"のところのrightsをnoneからread|writeに変更すれば動きそうかなと思い、設定してからrspecを実行したところ、見事成功!👊

事なきを得ました。

二度と起きないようにDockerfileを修正する

そうはいっても、現状だとDocker Imageを作り直すたびにnoneに戻ってしまうので、Dockerでビルドするときにsedでを書き換えるようにしておきました。

# ImageMagickのpolicy.xmlを修正してpdfを扱えるようにする
RUN sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml

そして、dockerをビルド後、再びテストを実行して問題ないことを確認!やったぜ!!

まとめ

まだPaperclip使ってるの!?とか言わないでやってください。色々あるんです!

会社のMacを初期化してセットアップし直した

ただの日記です。

ずっとMacの調子が悪くて、よくbundle installに失敗するようになって、その原因もわからなくて、そのため、開発環境のDocker化などに踏み切って、それはそれで功を奏していた。

patorash.hatenablog.com

普段の開発環境なら、まぁそれでいいのだが、時々他のプロジェクトの調査とかをするときにもbundle installでコケてしまい、それを動かすためだけにわざわざRubyのDocker環境を作るのが面倒なので、もう初期化してやろうと思って踏み切った。 ついでに、MojaveだったのをCatalinaにアップグレードしておいた。

ドキュメント系はクラウドにバックアップを作成しておいて、あとは手動でセットアップした。昔にAnsibleで作ったりもしていたけれど、今回はもうzshを使いたかったのでやめた(前はfishを使ってた)。 もしかしたら、fishとなにかしらの設定とかの相性が悪くてパスの通し方に失敗していたのかな?とも思う。

セットアップでやったこと

会社のPCなのでウィルス対策ソフトとかOfficeとかのツールのインストールは事前にやったとして、その後にしたことを列挙しとく。

  • homebrewのインストール
  • pecoのインストール
  • ghqのインストール
  • dockerのインストール(brew caskで)
  • rbenvのインストール(gitで)
  • goenvのインストール(gitで)
  • nodenvのインストール(gitで)
  • pyenvのインストール(gitで)
  • JetBrains Toolboxのインストール
  • Rubymineのインストール
  • VS Codeのインストール
  • オレオレdotfilesの適用(シンボリックリンク
  • zplugのインストール
  • .zshrcのカスタマイズ

まぁあとは細々としたのを並べるとSkitchとかCyberDuckのインストールとか、夜フクロウのインストールとか…。

zsh使いこなしたい

まだ全然使いこなせてはいないけれど、とりあえずzplugが便利だったのはこの前の家のWSL2のUbuntuの設定のときに体験したので、マルっとコピーしておいた。ところが、WindowsだとAltキーだが、MacだとOptionキーだったりして、そのあたりで動いてくれなかったので、Macではbindkeyの設定を多少変更した。それくらいの変更は必要ではあったが、MacWindows(WSL2)でShellの設定をほぼ統一できたのは嬉しい。

zplugで入れたプラグイン

入れたプラグインは、以下の通り。

bundlerプラグインは、bundle execbeにしたり、bundle installbiにするエイリアスが定義されているやつ。便利。 同様に、docker-compseもdocker-compose updcupになっていたりする。タイプ数が減るので助かる。 テーマは、draculaに慣れているのでdraculaにしておいた。

.zshrcの一部を晒しておく。

export GOENV_ROOT="$HOME/.goenv"
export PATH="$GOENV_ROOT/bin:$PATH"
eval "$(goenv init -)"

export RBENV_ROOT="$HOME/.rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"

export NODENV_ROOT="$HOME/.nodenv"
export PATH="$NODENV_ROOT/bin:$PATH"
eval "$(nodenv init -)"

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

export ZPLUG_HOME=$HOME/.zplug
source $ZPLUG_HOME/init.zsh

zplug "modules/history", from:prezto
zplug "modules/directory", from:prezto
zplug "plugins/git", from:oh-my-zsh
zplug "plugins/docker-compose", from:oh-my-zsh
zplug "plugins/bundler", from:oh-my-zsh

# Load theme file
zplug 'dracula/zsh', as:theme
DRACULA_DISPLAY_TIME=1
DRACULA_DISPLAY_CONTEXT=1

# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=1000
SAVEHIST=1000
setopt autocd beep extendedglob nomatch notify
# bindkey -e

# End of lines configured by zsh-newuser-install
# The following lines were added by compinstall
zstyle :compinstall filename "$HOME/.zshrc"

autoload -Uz compinit
compinit
# End of lines added by compinstall

if ! zplug check --verbose; then
  zplug install
fi

zplug load --verbose

pecoやghqと連携させるための関数定義で参考にしたページ

qiita.com

qiita.com

シェルをもっと使いこなしたい。