ログ

ActionView::Template::Error (`magick convert /tmp/ActiveStorage-216461-20231214-1-1ekdlk.jpg[0] -auto-orient -resize 88x88> /tmp/image_processing20231214-1-x899tq.jpg` failed with status: 1 and error:
convert: no decode delegate for this image format `JPEG' @ error/constitute.c/ReadImage/746.
convert: no images defined `/tmp/image_processing20231214-1-x899tq.jpg' @ error/convert.c/ConvertImageCommand/3362.
):
    3:     .page-content-header__user
    4:       = link_to user, class: 'page-content-header__user-link' do
    5:         span class="a-user-role is-#{user.primary_role}"
    6:           = image_tag user.avatar_url, title: user.icon_title, class: 'user-profile__user-icon-image a-user-icon'
    7:   .page-content-header__end
    8:     .page-content-header__row
    9:       .page-content-header__before-title

app/models/user.rb:587:in `avatar_url'
app/views/users/_profile.html.slim:6
app/views/users/_profile.html.slim:4
app/views/users/show.html.slim:39

ActiveStorageでconvertして表示するときにJPEGがconvertできてない。

Cannot convert pdf files · Issue #6935 · ImageMagick/ImageMagick

this is because in alpine:18 there was basically one imagemagick package, and in alpine:19 the packages have been split up

see also https://pkgs.alpinelinux.org/packages?page=1&name=imagemagick%2d%2a&branch=v3%2e19

どうやらalpine18まではimagemagickというパッケージに色々入ってたのが、alpine19からは各種モジュールは別パッケージになった模様。

Dockerfile:

RUN apk add --no-cache imagemagick imagemagick-heic imagemagick-jpeg imagemagick-pdf imagemagick-svg imagemagick-webp

各種モジュールはimagemagick-xxxxというパッケージになっているのでこれらを入れるようにしたら直りました。

考えがまとまってないことについてブログに書いていこうと思った次第です。

新規プロジェクトについては、下記のどっちかでいいと思った。

  • Railsデフォ(Hotwire)
  • Rails APIモード + Next

前者は少人数に向いてて、後者はバックエンドとフロントエンドでチームが分かれる以上の人数の場合。 そして、Reactと組み合わせるんだったら絶対Routerが必要なのでNextでいいじゃん。

何が言いたいかというと、Rails非APIモード + Reactは既存案件の改修とかで使われるだけと想定して、スクールで教える必要は無いってこと。

そして、バックエンドコースとするならHotwireを使って、フロントエンドコースでTypescriptとNextをやる。 これでバックエンドコースと言いつつフルスタックやっていて卒業まで年単位でかかる問題を解決する。フルスタック勉強したい人はフロントエンドコースも両方受講すれば良しというようにする。

辛いのはチーム開発(スクラム)のカリキュラムで取り組むFBCのEラーニングツールがまさにRails非APIモード + Reactになっているってこと😭 (まさに既存案件だからね)

本番環境の状態を見る必要があって稀に(3ヶ月に一回ぐらい)必要になるんだけど、毎回忘れてるのでメモ。

Cloud SQL Auth Proxyを起動する。

$ cloud_sql_proxy -instances=xxxxxxx-123456:asia-northeast1:xxxxxx=tcp:5433

ローカルのpostgresも使いたいので5433をproxyする。

railsのdatabase.ymlの設定は下記のようにする。

development:
  <<: *default
  database: xxxxxxxx_development
  host:     '127.0.0.1'
  port:     5433
  database: 'xxxxxxxx_production'
  username: 'xxxxxxxx'
  password: 'xxxxxxxx'

hostはlocalhostではダメで127.0.0.1じゃないとダメなのがハマりポイント。 毎回、「あ〜そうだったなぁ〜」って思い出すまでに試行錯誤に1時間ぐらいかかる。

最近のrailsでのパスワード認証gemって何使ってます?

The Ruby Tool BoxのWeb Authentiationカテゴリーを参照。

devise

やってくれることは多いがカスタマイズしづらいので嫌う人も多い。俺はこれ使ってる。 しかし登場から時間が経ち、railsの仕様に追従していくにつれて初期の設計に無理がきてる感。特にrails7からはさらに。

sorcery

やってくれることは少ないが、カスタマイズしやすい。bootcampのアプリはこれを使ってる。(確か @hrysd が入れた) リニューアル版sorcery(sorcery-rework)が別リポジトリで進んでるが、当分完成しそうにな。

authlogic

使ったことないけどちょっと古い感?

clearance

使ったことないけどちょっと古い感2

railsの基本機能を使って自作

これが多いのかも?

個人的には認証などのセキュリティが大きく絡むところはなるべくgemなどみんなが見ている(セキュリティパッチがすぐ入りやすい)ところのを使いたいな〜と思っております。

みなさんのプロジェクトではどんな感じでしょう? 温度感が知りたい感。

フィヨルドブートキャンプというプログラミングスクールのEラーニングアプリをCloud Run + Railsで動かしています。

1ヶ月使ってみた結果、8,000円ぐらいでした。

Image from Gyazo

Cloud Runが300円でCloud SQLが7,000円って感じです。Cloud Buildとかちょこまかしたのはありますが誤差の範囲。

Cloud Runは1コンテナだったら1日10円ぐらいなんですよね。信じられないほど安い。

これでDockerイメージ放り込んでおけば自動スケールの環境が手に入るならほとんどの仕事のアプリはこれでいい気がします。パフォーマンスもいいし、これからのアプリは全部これで行こうと思います。

mentionable gemで簡単にmentionが実装できます。(こういうやつ → @komagata)

komagata/mentionable

インストール

gem 'mentionable'
$ bundle install

使い方

app/models/comment.rb:

class Comment
  mentionable_as :body

  def after_save_mention(new_mentions)
    p new_mentions # => ["@komagata", "@machida"]
  end
end

Commentモデルのbodyにmentionが含まれる文章が保存される場合、mentionable_asでそのカラムを指定したらデフォルトでafter_save_mentionメソッドが呼ばれるので実装して置けばOK。

そのカラムにメンションが含まれていた場合、そのメソッドがコールバックされます。

class Comment
  mentionable_as :body, on_mention: :on_mentioned, regexp: /:\w+:/

  def on_mentioned(new_mentions)
    p new_mentions # => [":komagata:", ":machida:"]
  end
end

コールバックメソッドの名前とメンションを抽出するための正規表現は独自のものが指定できる。

便利メソッド

comment = Comment.create(body: '@nobunaga @hideyosi Hi guys.')
comment.mentions # => ["@nobunaga", "@hideyosi"]
comment.new_mentions? # => true

comment.update(body: '@nobunaga @hideyosi @ieyasu Hi guys.')
comment.mentions # => ["@nobunaga", "@hideyosi", "@ieyasu"]
comment.mentions_were # => ["@nobunaga", "@hideyosi"]
comment.new_mentions # => ["@ieyasu"]
comment.new_mentions? # => true

#mentionsでメンションが取れる。

メンションを自分で実装するときの面倒な仕様として、

「メンションを含むテキストがupdateされた場合に増えた分のメンションだけ欲しい。(updateされるたびに通知が行くとうざい)」

というのがありますが、mentionable gemでは最初から新しく増えた分のメンションだけがコールバックメソッドに渡ってくるので楽です。

それらを自分で取る各種メソッドもあります。

  • #mentions: メンション全部
  • #mentions?: メンションある?
  • #new_mentions: 新しいメンション
  • #new_mentions: 新しいメンションある?
  • #mentions_were: 古いメンション

実際のサービスではコールバックメソッドの中でサイト内通知や通知メールを送ったりすればOK。

フィヨルドブートキャンプというプログラミングスクールで初めてのPRに対するレビューをたくさんやっています。これらの指摘は世界中で行われていると思うので無駄が減るように書きました。

Files changedを確認したか

Image from Gyazo

真っ先に注意したい点。

ローカルの自分のエディタ上で確認していたとしても、PRを作ったら必ずFiles changedを確認する癖をつけよう。GitHubのソースコードビューワーの機能で色々と気づける点もある。

明らかにFiles changedを一回も見てないなというPRはレビュワーもそれと分かります。

lintを通しているか

rubyだったらrubocop、jsだったらeslint

どういうルールが良いかという高度は話題は置いておいて、まずはlintを通しているか否か。

ファイルの末尾に改行があるか

これ

Image from Gyazo

どのエディターでも設定で自動的に入るようにできるので設定すること。

なぜ最終行に改行が必要なのか - komagataのブログ

同じコミットログが続いていないか

適切な文章などの高度な話題以前に明らかに適当になっている場合がある。コミットログというのはちゃんと見られるものだということを理解しよう。

コミットログが英語/日本語になってないか

プロジェクトのルールに合わせましょう。フィヨルドブートキャンプでは統一されていればどちらでもいいです。

コミットログが雑になってないか

modifyだけ、追加だけは後から見た人が困るので駄目。困る人には1ヶ月後の自分も含まれる。

コミットしたユーザーアイコンがOctcatになっていないか

gitクライアントに設定したemailアドレスがGitHubのユーザーのメールアドレスと違う場合にこうなる。

他のチームメンバーからすると「謎のアイコンの人がコミットしてる!」という見た目になる。

これをやると他のメンバーに「ああ、普段コード書いてない(GitHubを使ってない)人なんだな・・・」という生暖かい視線を浴びる羽目になる。

不要なファイルをコミットしてないか

.DS_Store(Macのみ)とかxxx~(viのみ)とかその人にしか必要ないファイルを含めてしまってないか。開発に参加するみんなに必要なものだけを含めるようにしよう。

無意味なファイルがないか

generatorが作成した無意味なファイルは削除しよう。実装のないmoduleとか、中身のないtest、fixturesとか。

「これはgeneratorが勝手に作成したんで」

といってファイルがカオスになってるプロジェクトは誰も触りたがらない。

一つ一つどんな意味を持っているのか調べよう。

gemのgroupが適切か

testでしか使わないgemがgroup無しで全groupで読み込まれている。必要なところだけにしよう。

不要なrespond_toがないか

jsonでアクセスする必要が無いのにscaffoldのコードをそのままで残っている。htmlだけが必要ならrespond_toformatは削除しよう。削除するときにrespond_toformatが何をやっているのか調べた上で消すのも忘れずに。

何でもリファクタリングと言ってないか

リファクタリングはプログラムの振る舞いを変えずに内部構造を変えることなので、ちょっとした修正という意味で使ってはいけない。

秘密の情報がコミットされていないか

oauthのsecretとか。コード中では環境変数にしておこう。

これをやると、gitで過去を修正したとしてもGitHubのキャッシュに残ってしまい、完全に消すにはGitHubのサポートに連絡するとか面倒なことになる。

チームメンバーが「やっちまったな・・・」という顔になる。

.gitignoreは適切か

.DS_Storeはmacだけのファイル。.ideaはJetBrainsのエディター独自のファイル。そういった特定の環境の人向けのファイルは.gitignoreに含めるべきじゃない。

プロジェクト毎の設定じゃなくて自分のマシン固有の設定に書くべき。

大量の依存gemがコミットされていないか

gemのインストール場所をvendro/bundleとかにしてあって、その中にある大量のgemのファイルがコミットされてしまっていないか確認すること。

ネイティブバイナリが含まれたgemもあるので環境によって違うので各自がインストールするものです。

マジックナンバーが無いか

これ。

マジックナンバー (プログラム) - Wikipedia

メソッドが長すぎないか

「1メソッドは五行以内に収めるべし」というSandi Metzルールというものがあります。

そこまで徹底しなくて良いですが、何十行もあるとさすがに見辛いので修正が必要です。

綺麗な設計を身に付けるためのSandi Metzルール | A-Listers

CIをパスする前にレビュー依頼をしない

自分は何にも変えてないから通るはずだと過信しない。

理解せずコピペしてないか

ググった内容を自分のコードに取り入れることは問題ありません。しかし、その内容を自分で理解せずそのまま使うのはよくないです。理解していないコードでは何が起きるか分かりません。

日本語の作文をするのに似た内容だからといって他の本からそのまま取ってきたら違和感のある文章になってしまうのと同じように、プログラムも変数名や構造を自分のプログラムに合わせずにそのまま使えることはほぼありません。理解しているプログラマーにとっては明らかに違和感のあり無駄のあるコードに見えます。

なので、

「自分の書いたこの部分が何をやってるか理解してる?」

と先輩に聞かれると言うことがよくあります。

意味を理解した上で自分のコードの文脈に合わせた内容に変えて使いましょう。

5.2系では読み込まれてたんだけど、6.0.1にしたらデフォルトでは読み込まれなくなってるみたい。zeitwerkになったからかしら。

手動でrequireすればOK。

require "active_record/fixtures"

class NotificationMailerPreview < ActionMailer::Preview
  def came_comment
    id = ActiveRecord::FixtureSet.identify(:report_5)

    # ....
  end
end

「開発環境のユーザーのパスワードって何?」

みたいな情報の共有って面倒ですよね。any_login入れちゃうのがいいかも。

any_loginを入れると画面の左下にアイコンが出てきて、そこをクリックするとユーザーが一覧できるプルダウンメニューが出てきます。それを選択するだけでそのユーザーでログインできるというもの。

似た仕組みを用意してる人が多いとは思いますが、無いなら導入おすすめです。

igorkasyanchuk/any_login: Easy way to login as any user in system

認証ライブラリはDevise, Authlogic, Clearance, Sorceryなど色々対応してます。

Image from Gyazo

フィヨルドブートキャンプのアプリに入れてみました。

fjordllc/bootcamp: プログラマー向けEラーニングシステム

フィヨルド宛にwillnetさんからRuby on Rails 6 エンジニア 養成読本をいただきましたー。

Image from Gyazo

rails6になって新しく押さえておかなきゃいけないところをチェックしたかった自分にはちょうど良い本でした。

特にこれらはRailsGuideでもまだWIP状態なので本にまとまってるのはわかりやすかった。

  • Action Text
  • Action MailBox
  • Multiple Database

さらにWebpacker、StimulusについてはREADME・公式サイト以外の情報はあまりないので少しでも記述されている本は集めたい気がします。

testunit(minitest)信者として一番良かったのは、rspecじゃなくてminitestでのテストを一通り説明してあるところ。

これの本は人によって自分が詳しく知ってるところ、弱いところが違うのでありがたい箇所も人それぞれだと思います。(僕はEarly Hints知らなかったので助かった)

ちょっとだけRailsから離れてて復帰した人、Rails6の新機能を押さえたい人にとっては最適な本だと思います。