行動すれば次の現実

ほどよくモダンなシステム開発を目指しています。メインテーマは生産性、Ruby、Javascriptです。

Rails

Axlsxで出力したExcelをRSpecでテストする方法

RubyでExcelのインポート、エクスポートを実装する場合は、Axlsxを使用することが多いかと思います。 Axlsxでエクセルをインポートする処理をRSpecでテストするというコードはよく見かけるのですが、 エクスポートに関してはあまり見たことがありません。 先…

Railsアプリが爆速になるパフォーマンスチューニング集

Railsアプリを速くするためのパフォーマンスチューニング集をまとめました。 これらの手法を用いることで、弊社アプリにおいて、今まで30秒ほど掛かっていた処理が1.5秒まで短縮することができました。 あくまでもアプリケーションレイヤーでできるパフォー…

Rails7でReactを使う場合はimportmapはオススメできない

Rails7からJavascriptバンドラーとしてNode.jsが非依存のimportmapが標準機能に採用されました。 早速、importmapを使ってReactを使用した開発を試みてみましたが、結論としてはimportmapは使用しないことになりました。 Reactの場合はimportmapをオススメで…

Herokuで可用性の高いサービスを運用するために入れておきたいアドオン3選 | Rails

弊社では多くのWebサービスをHeroku上で稼働させています。 初めてローンチした当初は数々のトラブルが発生して可用性が不安定な時期がありましたが、現在は可用性の高いサービス運用が実現できております。 それが実現できているのはアドオンのおかげと言っ…

既存のRailsアプリをHerokuにデプロイして本番稼働させるまでの手順

既存のRailsアプリをHerokuにデプロイして本番稼働させるまでの手順を説明します。 運用面を考慮した細かな設定も含みますので、公式ドキュメントよりも豊富な内容になっております。 1. Herokuで新しいアプリを作成する Heroku管理画面からCreate New Appし…

Rails6+Webpacker+Postgresql+SidekiqでDockerの開発環境を構築する手順

すでに稼働しているRailsアプリをDocker化する手順を紹介します。 Dockerの公式ガイドだけでは手順が不足している部分があったので、細かな部分も含め解説を加えています。 環境構成 Dockerfile docker-compose.yml .dockerignore entrypoint.sh config/data…

Webpacker3から5にアップグレードする方法 | Rails

最近、開発端末をMacBook Pro M1 Maxに乗り換えたところ、webpackのコンパイルが極端に遅くなりました。 思えばwebpack3のままメンテナンスを怠っていたので、これを機にwebpack4にアップグレードすることになりました。 Webpackerをv3からv5にアップグレー…

ScoutAPMのトレース情報にユーザーIDを付加する方法

ScoutAPMを使ってモニタリングしているとトランザクションとログインユーザー情報を紐付けたいと思ったことはありませんか? そのような場合は、ScoutAPMのCustom Contextという機能を使うことでトランザクションに対して付加情報を付けることが出来ます。 C…

RailsのLogにuser idを出力する方法

Ruby on Rails5でリクエストログにユーザーIDを追加する方法を説明します。 ミドルウェアの修正は不要ですので、気軽に取り入れることができると思います。 実装内容 config/initializers/logging.rb Rails.configuration.log_tags = [ :request_id, lambda …

Railsでよくエラーになるlibv8、therubyracer、mini_racerあたりを調べた

Railsアプリを構築しようとするときにbuildエラーになるライブラリの代表にlibv8、mini_racerなどが上げられると思います。(個人的感覚) 毎回gemを最新化することでなんとなく解決していたのですが、これではその場凌ぎしかなく応用が効きません。 しっか…

yarnコマンドで発生したgyp ERR!の原因究明と対処方法

アプリケーションのnode.jsのバージョンを上げて、yarn installコマンドを実行したら以下のようなエラーが発生しました。 1 error generated. make: *** [Release/obj.target/binding/src/binding.o] Error 1 gyp ERR! build error gyp ERR! stack Error: `m…

ActionMailerでOpenSSL::SSL::SSLErrorが発生してメールが送れない

ActionMailerで別ドメインのSMTPサーバー経由でメール送信しようとしたらOpenSSL::SSL::SSLErrorが発生してエラーになりました。 ※接続情報等は架空の値になっております。 ERROR -- : OpenSSL::SSL::SSLError ERROR -- : hostname "smtp.example.com" does …

Sidekiqで実装したWorkerをRSpecでテストする

Sidekiqで実装したWorkerクラスのRSpecでテストする方法をまとめました。 SidekiqをRSpecでテストする方法 Sidekiqのテスト手法には主に以下の2種類があります。 Sidekiq::Testing.fake!を使用したテスト キューへのジョブ登録(エンキュー)から、ジョブの実…

Turbolinksとcookieは相性が悪い

Javascriptでcookieに値を設定する処理を実装していたのですが、タイミングによって同じcookie名で重複してvalueが登録される事案が発生しました。 調査するとどうやらTurbolinksが原因であることがわかりました。 Turbolinksを有効にするとcookieのpathに適…

RailsでPostgreSQLの配列型の項目に対して検索をする

PostgreSQLの配列型に対して「〜を含む」という検索したかったので調べました。 配列型はアンチパターンなのですが、そこは目を瞑ってください。。 環境 ruby 2.7.4 rails 5.2.5 PostgreSQL 13.4 Migration ブログ(Blogs)に複数のタグ(tags)を付与できるテー…

CarrierWaveでAWS S3 にファイルをアップロードしようとするときに発生する403エラーについて | Rails

carrierwaveとfog-awsを使用してファイルをアップロードしようとしたところ以下のエラーが発生しました。 Excon::Error::Forbidden: Expected(200) <=> Actual(403 Forbidden) このエラーの原因と対処法を整理しましたので同様のことでお悩みの方はぜひ参考…

Hashを使って大量のActiveRecordをキャッシュに載せる方法 | Ruby on Rails

ループ処理の中で、あるテーブルに対してアクセスしなければならない場合、ループ毎にテーブルをfindするのは非効率かもしれません。事前に必要なテーブルデータを抽出しておき、そのキャッシュを使って処理するほうが効率的な場合があります。 しかし、この…

Rubyで文字列がURL形式かどうか正規表現でチェックする | Rails

Rubyで文字列がURL形式であるかチェックする場合は URI::DEFAULT_PARSER.make_regexp.match を使用します。 これを使用することで、引数に渡された文字列がURI形式であるかどうかをチェックすることができます。 引数の文字列がURI形式であればMatchDataオブ…

最低限知っておきたい!Railsのトランザクション実装例

Railsでトランザクションを使いたい方向けに実例を踏まえてわかりやすく解説をいたします。 RailsにおけるTransaction 例外が発生すればロールバックされる transactionブロック内でrescueするとロールバックされないので注意! ロールバック後も処理を継続…

ルーティングをネストする際のresourcesとresourceの使い分け | Rails

Railsで開発したことがある方は、ルーティングをネストしようとした場合に、resourcesとresourceのどちらを使用すべきか迷ってしまったことがあるのではないでしょうか?(私もその一人です) この記事ではresourcesとresourceの使い分けについて、親リソー…

RailsアプリでRubyバージョンアップする方法(2.6 to 2.7)

この記事では、Railsアプリをrbenvを使用してv2.6.8からv2.7.4にアップグレードする方法を説明します。 インストールされているrubyのバージョンアップを確認する rbenv versions インストール可能なrubyのバージョン一覧を確認する rbenv install --list-al…

HerokuのR14エラーをScoutAPMで対策する方法 | Rails

Herokuではメモリ使用量がプランの上限を超えるとR14エラーが発生します。 R14はスワップメモリが発生していることを意味しており、発生するとアプリケーションの処理速度が著しく低下してしまいます。 このままメモリ使用量が200%を超えてしまうと、R15エラ…

ActiveModel valid?でバリデーション例外を発生させる | Rails

ActiveModelのvalid?はモデルのバリデーションを実行して真偽値を返却するメソッドですが、バリデーションエラー時に例外を発生させたいことがあったので調べてみました。 通常ならsave!やcreate!で対応できますが、Activerecord-importのBulkインサートの永…

クエリ文字列から特定のパラメータを削除したい | Ruby On Rails

クエリ文字列から特定のパラメータのみを削除する方法を説明します。 実装 uri = URI.parse('https://www.example.com?hoge=1&fuga=2&piyo=3') query = Rack::Utils.parse_nested_query(uri.query) query.delete('fuga') uri.query = query.to_param uri.to_…

Railsのカスタムバリデーションで複数項目の相関をチェックしたい

開始日と終了日を入力するシステムで、期間の大小チェックと期間の日数チェックを行いたい場合があります。 カスタムメソッドで実装するケースはよく見受けられますが、カスタムバリデーションとして使い回したい思ったので実装してみました。 ※あくまでも簡…