行動すれば次の現実

テック中心の個人ブログ

M1 Macbook Proにrbenv経由でRubyをインストールしようとしたらエラーになってハマった

f:id:furu07yu:20220324164425p:plain M1 Max Macbook Proにrbenv経由でRubyをインストールしようとしたところ、エラーが発生してインストールできませんでした。

この原因調査と対応にほぼ丸一日時間を費やしてしまったので、戒めも込めて記事にすることにしました。 誰かのお役に立てれば幸いです。

readlineでエラーが発生している

rbenv経由でRuby 3.1.0をインストールしようとしたら以下のエラーで失敗になってしまいました。

Downloading ruby-3.1.0.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.gz
Installing ruby-3.1.0...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 12.2.1 using ruby-build 20220218)

Inspect or clean up the working tree at /var/folders/t3/xx1z7jpj0zbfj_rwd9jh8bm00000gn/T/ruby-build.20220323144141.55529.x88PvV
Results logged to /var/folders/t3/xx1z7jpj0zbfj_rwd9jh8bm00000gn/T/ruby-build.20220323144141.55529.log

Last 10 log lines:
compiling ossl_x509ext.c
compiling ossl_x509name.c
compiling ossl_x509req.c
compiling ossl_x509revoked.c
compiling ossl_x509store.c
linking shared-object psych.bundle
linking shared-object date_core.bundle
installing default openssl libraries
linking shared-object openssl.bundle
make: *** [build-ext] Error 2

Results logged to /var/folders/t3/xx1z7jpj0zbfj_rwd9jh8bm00000gn/T/ruby-build.20220323144141.55529.log と記載があるように、まずはログを確認してみます。

compiling readline.c
compiling ossl_cipher.c
linking shared-object objspace.bundle
compiling psych_emitter.c
readline.c:1903:37: error: use of undeclared identifier 'username_completion_function'; did you mean 'rl_username_completion_function'?
                                    rl_username_completion_function);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    rl_username_completion_function
readline.c:79:42: note: expanded from macro 'rl_username_completion_function'
# define rl_username_completion_function username_completion_function
                                         ^
/usr/local/opt/readline/include/readline/readline.h:485:14: note: 'rl_username_completion_function' declared here
extern char *rl_username_completion_function PARAMS((const char *, int));
             ^
compiling psych_parser.c
1 error generated.
make[2]: *** [readline.o] Error 1
make[1]: *** [ext/readline/all] Error 2
make[1]: *** Waiting for unfinished jobs....

ログにはmake[2]: *** [readline.o] Error 1と出力されていますので、readlineでエラーが発生していることが確認できます。

make[1]: *** [ext/readline/all] Error 2rl_username_completion_functionなどの文言も気になります。

使用されているreadlineに問題がありそう

  • m1 mac rbenv install
  • BUILD FAILED (macOS 12.2.1 using ruby-build 20220218)
  • rbenv readline m1 mac
  • "rl_username_completion_function"

等の文言で検索してヒットした記事を参考にしたところ、以下のようなコマンドでインストールするのが有効だと分かりました。

RUBY_CONFIGURE_OPTS=--with-readline-dir="$(brew --prefix readline)"
rbenv install 3.1.0

このコマンドではhomebrew経由でインストールされているreadlineを使用してrubyをインストールするというオプションを指定しています。

今回のようなエラーの場合、ほとんどのケースではこのコマンドを実行することで無事にインストールできるかと思います。

しかしながら私の環境では、このインストール方法を用いても依然として同様のエラーが発生してしましました。

homebrew自体に問題がありそう

エラーログをよく確認してみるとruby-build: using readline from homebrewと出力されていますので、すでにhomebrew経由でreadlineを使用していたということが確認できました。

ということはhomebrewでインストールされているreadline自体に問題がありそうだと考えました。

brew update readlineを実行してみても特に変化はありません。

改めて記事を検索していたところ、この記事にヒントが有りました。

Building Ruby 3 on Mac M1 ARM — brandur.org

readlineの向き先としてhomebrewにインストールされているモジュールを使用するオプションを指定するのですが、Rosetta版のとARM版とでhomebrewのインストール先が違うという点でした。

確認してみると、私のmac上にはRosetta版がインストールされていました。

homebrewをアンインストールして、改めてARM版のhomebrewをインストールしたところ、Rubyのインストールが正常に行われました。

結論

私の場合、ARM版のhomebrewがインストールされておらず、コンパイルに失敗するというのが原因でした。

思い返してみるとintel Macから移行アシスタントを使用してM1 Macの環境構築をしていました。その際、あまり意識せずにRossetaの使用確認を許可したのだと思われます。

移行後はDocker環境で動かすことがほとんどでしたので、homebrewを使用する機会が今の今まで訪れず、ようやく問題が露呈されたということになります。

ひとまず一件落着です。

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

f:id:furu07yu:20220316185416p:plain

弊社では多くのWebサービスをHeroku上で稼働させています。

初めてローンチした当初は数々のトラブルが発生して可用性が不安定な時期がありましたが、現在は可用性の高いサービス運用が実現できております。

それが実現できているのはアドオンのおかげと言っても過言ではありません。

今まで様々なアドオンを試してきましたが、本当に役に立ったのは後述する3つのアドオンに限られます。

今回はこの3つのアドオンを紹介したいと思います。

Papertrail

Papertrail - Add-ons - Heroku Elements

Papertrailはログを管理するためのアドオンです。

Herokuアプリ単体ではログは保存されません (正確には最新の1500行が1週間保存されます。それを超えるとログを閲覧することができなくなります)

そのため、ログを保存させるためのアドオンを別途使用する必要があります。

Papertrailを使用することで大量のログを一定期間保存することができます。また、保存したログを高度な条件で検索したり、特定の文言のログが出力された際に外部サービスに通知することができます。

Papertrailの主な機能と特徴

  • 無料から使用できる(1日のログのサイズ、保存期間などによって料金プランが定められている)
  • ログをリアルタイムに閲覧できる
  • 詳細な条件を指定してログを検索できる
  • アラート機能により特定の文言が含まれるログを外部サービス(メールやSlack等)に連携できる

Scout APM

Scout APM - Add-ons - Heroku Elements

ScoutAPMはアプリケーションパフォーマンス管理ツール(APM)です。

HerokuにもMetricsという機能があります。サービス全体での大まかなパフォーマンス監視は可能ですが、それはあくまでもおまけ程度と考えたほうが良いです。

ScoutAPMを使用することで、N+1クエリやメモリブロートの原因、パフォーマンスの異常を詳細に調査することができます。

エンドポイントやリクエスト単位でトランザクションを追跡することができるので、ボトルネックとなっている箇所を詳細なレベルで把握することが可能です。

PapertrailでR14やH12等の文言でアラートを検知して、ScoutAPMで調査するような改善を繰り返すのがオススメです。そうすることでアプリの信頼性が向上して顧客にストレスなく価値を提供し続けることができます。

ローンチした最初のうちは有料プランで使用して、ある程度ボトルネックを洗い出し終えて、アプリが安定稼働してきたら無料プランに切り替えるのが良いのではないかと思います。

ScoutAPMの主な機能と特徴

  • 無料から使用できる(トレースできる期間などによって料金プランが定められている)
  • エンドポイントやリクエスト単位でトランザクションを追跡することができる(競合サービスのNewRelicでは出来ない)
  • レスポンスタイム、メモリブロート、SQLスロークエリなどの切り口からボトルネックを調査できる
  • Githubと連携することでコード単位で追跡することができる

Pingdom

Pingdom - Add-ons - Heroku Elements

Pingdomはアプリの死活監視を行うサービスです。

Herokuアプリ自体がダウンしまった場合、それを検知させる外部のサービスが必要です。

Pingdomを使用することで、世界中にある100以上の拠点からアプリを監視することができます。 ヘルスチェック(死活監視)やパフォーマンステストはもちろん、トランザクションテスト(E2E)を実行する機能もサポートされているので、これ一台で様々な監視を行うことが出来ます。

特にE2Eテストはオススメです。E2Eテストというとハードルが高いイメージがありますが、PingdomのTransactionsという機能を使用することで直感的なUIで簡単にシナリオテストを作成することが可能です。

Pingdomの主な機能と特徴

  • 有料プランのみ対応
  • Real User Monitoringでユーザーの属性などをリアルタイムに把握することが出来る(GoogleAnalyticsに似た機能)
  • Uptimeで複数のアプリに対して死活監視することが出来る。チェック頻度や通知方法など細かな設定が可能
  • Page Speedでアプリのパフォーマンステストをすることができる
  • Transactionsで簡単なE2Eテストを作成して定期実行することが出来る。「ログインして特定のページで任意の操作を行う」などのシナリオが簡単に作成可能

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

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

運用面を考慮した細かな設定も含みますので、公式ドキュメントよりも豊富な内容になっております。

1. Herokuで新しいアプリを作成する

Heroku管理画面からCreate New Appします。

任意の名前を入力してくHerokuアプリを作成してください。

2. ビルドパックを登録する

SettingsタブのBuildpacksから任意のビルドパックを登録します。 Webpackerを使用しているアプリの場合はnodejsとrubyを登録します。

3. GitHubと連携する

Heroku上にデプロイできるようにGitHubにリモートリポジトリを登録します。

heroku git:remote -a hello-your-heroku-app-name

git remote -vでリモートリポジトリの設定を確認するとHerokuと連携されていることが確認できます。

git remote -v

heroku  https://git.heroku.com/hello-your-heroku-app-name.git (fetch)
heroku  https://git.heroku.com/hello-your-heroku-app-name.git (push)

4. Herokuにデプロイする

下記コマンドによりHerokuにデプロイします。 デプロイが成功すると、最小限の構成でDynoやDBが構築されます。

git push heroku master

5. タイムゾーンの設定

Herokuのタイムゾーンを東京に設定します

$ heroku run bash
~ $ date
Mon Mar 7 02:35:04 UTC 2022
~ $ exit ※一旦抜けます
$ heroku config:add TZ=Asia/Tokyo
~ $ date
Mon Mar 7 11:35:48 JST 2022

DBのタイムゾーンを東京に設定します

$ heroku pg:psql
DATABASE=> select current_timestamp;

       current_timestamp
-------------------------------
 2022-03-07 08:49:45.681203+00
(1 row)

DATABASE=> alter database データベース名 set timezone = 'Asia/Tokyo';
DATABASE=> \q ※一旦抜けます

$ heroku pg:psql
DATABASE=> select current_timestamp;
       current_timestamp
-------------------------------
 2022-03-07 17:51:08.162538+09
(1 row)

6. DBの構築

DBを構築します。必要に応じてseedを流します

heroku run rake db:migrate
heroku run rake db:seed

7. 環境変数の設定

$ heroku config:add WEB_CONCURRENCY=1
$ heroku config:add LANG=ja_JP.UTF-8

8. 必要なアドオンをインストール

必要があればアプリで使用するアドオンをインストールします。

弊社のプロジェクトの場合は以下のアドオンをインストールします

  • Heroku Redis
  • Papertrail
  • Scout APM

9. アプリの起動確認

最後にアプリの起動確認をして一通りの構築作業は完了です

heroku open

本番稼働に備えて

本番稼働に備えて以下の設定を行うことをオススメします。

DynoをHobbyプラン以上にする

DynoはHobby以上でなければ一定時間でスリープしてしまいますので、最低限Hobbyプラン以上にする必要があります。

DBをStandard0以上にする

Freeだと10,000レコードの制限があり、Hobbyだとインメモリデータベースではないので速度が遅いです。 そのため、Standard0以上をオススメします。

DBのアップグレード手順は下記の記事を参考にしてみてください。

HerokuのDBを有料プラン(Hobby)に切り替える方法 - 行動すれば次の現実

独自ドメインの設定

ドメインにherokuapp.comが付いてしまうので独自ドメインを設定しましょう。 独自ドメインを設定するにはDynoがHobby以上である必要があります。

GitHubリポジトリを複製する方法

GitHub上の既存リポジトリを複製して、新しいリポジトリを作成する方法を説明します。

基本的な内容はこちらの公式ドキュメントに載っているのですが、いくつか不足している箇所がありましたので説明を加えています。

前提

複製元のリポジトリをold_project、複製先のリポジトリをnew_projectとします。

1. 複製先のリポジトリを作成する

Githubの管理画面から複製先のリポジトリを事前に作成しておきます。

f:id:furu07yu:20220302170533j:plain

2. 複製元のベアリポジトリをクローンする

複製元のベアリポジトリをクローンします。

git clone --bare git@github.com:exampleuser/old_project.git

ベアリポジトリとはGitHubの更新情報のみを持つリポジトリのことを指します。

詳細が気になる方はこちらのQiitaを参照すると良いでしょう。 普段使用することは滅多にありませんので、おまじないのようなものだと割り切ってしまっても良いと思います。

3. 新しいリポジトリをミラープッシュする

複製元のベアリポジトリの更新内容を複製先のリポジトリにミラープッシュします。

cd old_project.git
git push --mirror git@github.com:exampleuser/new_project.git

--mirrorはベアリポジトリをプッシュする際に使用するオプションです。

4. 複製元のベアリポジトリのディレクトリを削除する

先程クローンした複製元のディレクトリは今後使用しませんので削除しておきます。

cd ..
rm -rf old_project.git

5. 複製先のリポジトリをクローンする

複製先のリポジトリを改めてクローンします。 これで複製は完了です。

git clone --bare git@github.com:exampleuser/new_project
cd new_project

既存の開発環境をDocker化する手順 Rails6+Webpacker+Postgresql+Sidekiq

すでに稼働しているRailsアプリをDocker化する手順を紹介します。

Dockerの公式ガイドだけでは手順が不足している部分があったので、細かな部分も含め解説を加えています。

環境構成

バックエンド
- Rails 6.0
- Ruby 2.7.4
フロントエンド
- Webpacker 5.4.3
- NodeJS 12.22.0
DB
- PostgreSQL 11.14
Worker
- Sidekiq
- Redis

Dockerfile

webサーバー(ruby)の起動をDockerfileで定義します。 コメントで各コマンドの内容を説明しています。

# FROMにはnodeとrubyのイメージを指定します
# FROMはDockerfileの最初に記載する必要があり、以降の命令はFROMで指定したイメージに対して行われます
# このDockerfileではrubyのイメージに対して命令を記載しているため、FROMの定義順番もnode、rubyである必要があります。
# nodeイメージに対してはASでエイリアスを付けます。エイリアスはCOPYコマンド等で使用することが可能となります
FROM node:12.22.0 as node
FROM ruby:2.7.4

# タイムゾーンに東京を指定します
ENV TZ Asia/Tokyo

# db:migrateなどで使用されるpostgresql-clientをイメージ上にインストールします
RUN apt-get update -qq && apt-get install -y postgresql-client

# WORKDIRでアプリをインストールするディレクトリを指定します。
# 以降の命令は、移動せずともそのディレクトリに対して実行することが出来ます
# ディレクトリが存在しない場合は作成されます
WORKDIR /your-appname

# ホスト上にあるGemfileとGemfile.lockをイメージのWORKDIRに転送します
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock

# イメージ上でbundle installを実行します
RUN bundle install

# entrypoint.shをイメージ上の/usr/bin/に配置します
# ENTRYPOINTで指定したコマンドはコンテナ稼働に必ず実行されます
# entrypoint.shはRailsアプリ特有の問題を対処します
# サーバー内にserver.pidというファイルが先に存在していたときに、サーバーが再起動できなくなる問題を回避するために使用されます
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

# nodeイメージ上にインストールされているnode関連モジュールを、rubyイメージでも実行できるように転送します
# nodejsとnpmの各種コマンドが実行できるようにシンボリックリンクを貼ります
COPY --from=node /usr/local/bin/node /usr/local/bin/node
COPY --from=node /usr/local/include/node /usr/local/include/node
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs && \
    ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm

# ホスト上にあるpackage.json yarn.lock .postcssrc.ymlをWORKDIRに転送します
COPY package.json yarn.lock .postcssrc.yml ./

# npmでyarnモジュールをイメージ上にインストールして、yarn installを実行します
RUN npm install --global yarn
RUN yarn install

# ホストのモジュールを全てWORKDIRに転送します
# .dockerignoreに記載されたモジュールは転送されません(node_modulesなど)
COPY . ./

# ポート番号3000で公開します
EXPOSE 3000

# コンテナ稼働時に以下のrailsコマンドが実行されます
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml

web、db、webpacker、worker、redisのコンテナを定義します。 コメントで各コマンドの内容を説明しています。

version: "3.9"
services:
  web:
    # Dockerfileを使ってbuildします
    build: .
    # コンテナ稼働時に実行されるコマンドです
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    # 擬似端末(キーボードによる入力)をコンテナに結びつけます(docker run -itの-tと同じ意味)
    tty: true
    # 標準入出力とエラー出力をコンテナに結びつけます(docker run -itの-iと同じ意味)
    stdin_open: true
    # ホスト側とコンテナ側のポートを3000でマッピングしています
    ports:
      - "3000:3000"
    environment:
      # WEBPACKER_DEV_SERVER_HOSTでdev-serverの接続先を指定しています
      WEBPACKER_DEV_SERVER_HOST: webpacker
    volumes:
      # ホスト上のカレントディレクトリ(.)の内容をコンテナ上の/your-appnameに割り当てます(バインドマウント)
      - .:/your-appname:delegated
      # コンテナ上のgemインストール先(/usr/local/bundle)をbundleという名前でボリュームに割り当てます
      - bundle:/usr/local/bundle
    depends_on:
      # dbコンテナが起動してからwebを起動します
      - db
  db:
    # postgresのイメージを使用します
    image: postgres:11.14
    volumes:
      # コンテナ上のデータ保存先(/var/lib/postgresql/data)をpostgresという名前でボリュームに割り当てます
      - postgres:/var/lib/postgresql/data
    # ホスト側とコンテナ側のポートを5432でマッピングしています
    ports:
      - "5432:5432"
    environment:
      # Postgreのユーザー名、パスワード、DB名を指定します
      POSTGRES_USER: app_dp
      POSTGRES_PASSWORD: password
      POSTGRES_DB: your_appname_dev
      # タイムゾーンに東京を指定します
      TZ: "Asia/Tokyo"
      # エンコーディングとlocaleを指定します
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C"
  webpacker:
    # Dockerfileを使ってbuildします
    build: .
    # コンテナ稼働時に実行されるコマンドです
    command: bash -c 'rm -rf public/packs/* || true && bin/webpack-dev-server'
    volumes:
      # ホスト上のカレントディレクトリ(.)の内容をコンテナ上の/your-appnameに割り当てます(バインドマウント)
      - .:/your-appname
      # コンテナ上のnode_modulesを使用するためボリュームを割り当てます
      - node_modules:/your-appname/node_modules
    ports:
      # ホスト側とコンテナ側のポートを3035でマッピングしています
      - '3035:3035'
    environment:
      # IPアドレスに0.0.0.0を指定します
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
  worker:
    # Dockerfileを使ってbuildします
    build: .
    # コンテナ稼働時に実行されるコマンドです
    command: bundle exec sidekiq -C config/sidekiq.yml
    volumes:
      # ホスト上のカレントディレクトリ(.)の内容をコンテナ上の/your-appnameに割り当てます(バインドマウント)
      - .:/your-appname
      # webコンテナと同じ名前のbundleボリュームを作成してgemを共有できるようにします
      - bundle:/usr/local/bundle
    environment:
      # redisのURLを指定します
      REDIS_URL: redis://redis:6379
    depends_on:
      # redisコンテナが起動してからwebを起動します
      - redis
  redis:
    # redisのイメージを使用します
    image: redis
    # コンテナ稼働時に実行されるコマンドです
    command: redis-server --appendonly yes
    ports:
      # ホスト側とコンテナ側のポートを6379でマッピングしています
      - "6379:6379"
    volumes:
      # コンテナ上のデータ保存先(/var/lib/redis/data)をredisという名前でボリュームに割り当てます
      - redis:/var/lib/redis/data
# 名前付きボリュームを定義します
volumes:
  bundle:
  postgres:
  redis:
  node_modules:

.dockerignore

dockerをビルドする際に必要のないファイルを.dockerignoreに記載します。 記載することでCOPYコマンドやADDコマンドでの転送時に対象外となります。

vendorやnode_modules等のコンテナで管理したいファイル群、転送の必要がないファイル群を除外しています。

/.bundle
/db/*.sqlite3
/db/*.sqlite3-journal
/log/*
/tmp/*
/storage/*
/node_modules
/yarn-error.log
/public/assets
/.byebug_history
/config/master.key
/vendor/*
/.idea/*
/config/master-staging.key
/public/packs
/public/packs-test
/node_modules
/yarn-debug.log*
/.yarn-integrity

entrypoint.sh

entrypoint.shはRailsアプリ特有の問題を対処します。 サーバー内にserver.pidというファイルが先に存在していたときに、サーバーが再起動できなくなる問題を回避するために使用されます。

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

config/database.yml

development:
  <<: *default
  # docker-composeで割り当てられたhostname(db)に変更します
  host: db
  # ・・・(以下省略)

config/initializers/sidekiq.rb

Sidekiq.configure_server do |config|
  if Rails.env.production?
    if ENV['REDIS_URL']
      config.redis = {url: ENV['REDIS_URL'], namespace: "dp_sidekiq_#{Rails.env}"}
    end
  else
    # docker-composeで割り当てられたhostname(redis)に変更します
    # config.redis = {url: 'redis://localhost:6379', namespace: "dp_sidekiq_#{Rails.env}"}
    config.redis = {url: 'redis://redis:6379', namespace: "dp_sidekiq_#{Rails.env}"}
  end
end

Sidekiq.configure_client do |config|
  if Rails.env.production?
    if ENV['REDIS_URL']
      config.redis = {url: ENV['REDIS_URL'], namespace: "dp_sidekiq_#{Rails.env}"}
    end
  else
    # docker-composeで割り当てられたhostname(redis)に変更します
    # config.redis = {url: 'redis://localhost:6379', namespace: "dp_sidekiq_#{Rails.env}"}
    config.redis = {url: 'redis://redis:6379', namespace: "dp_sidekiq_#{Rails.env}"}
  end
end

起動確認

1. イメージを作成する

docker-compose build --no-cache

2. イメージを元にコンテナを作成し、起動する

docker-compose up -d

3. migrationを流す

docker-compose run web rails db:migrate

4. アプリにアクセスする

http://localhost:3000/

よく使うdocker & docker-composeコマンド

最後によく使用するコマンドをまとめました。

# イメージを作成する
docker-compose build --no-cache

# コンテナを作成して起動する
docker-compose up

# コンテナを停止する
control + c

# コンテナの起動(バックグラウンド)
docker-compose up -d

# コンテナを停止する(バックグラウンド)
docker-compose stop

# コンテナを停止して削除する
docker-compose down

# webコンテナにログインする
docker exec -it your-appname_web_1 bash

# コマンドを実行する
docker-compose run web rails db:migrate

# イメージの一覧を出力する
docker images

# コンテナの一覧を出力する
docker ps -a

PostgreSQLで文字列型を数値型に安全にキャストする方法

PostgreSQLで文字列型を数値型に安全に型変換(キャスト)する方法を説明します。

文字列型の"1234"や"01234"を数値型の1234に変換したい場合などを想定しています。

文字列型を数値型にキャストする方法

CAST(code as integer)

このように記載することでcodeという文字列型のカラムをintegerにキャストすることができます。 ただし、このやり方だとcodeに数値以外の文字列が含まれている場合にキャストエラー(PG::InvalidTextRepresentation: ERROR等)が発生してしまいます。 例えば"12 34"ように半角スペースが入っている場合などにエラーが発生してしまいます。

安全にキャストする方法

CAST(REGEXP_REPLACE(code, '[^0-9]+', '', 'g') as integer)

キャストエラーを防ぐためにREGEXP_REPLACEを使って数値以外の文字列を空文字に置換してからCASTを実行します。 こうすることで安全にキャストすることができます。

Webエンジニアはどこに住むのが良いのか

首都圏でWebエンジニアが住むのにオススメな街はどこだと思いますか?

私は引っ越しが好きなので、今までいろいろな街に住んできました。 それぞれの街に良いところ、悪いところがあります。

せっかくなので、今まで住んだ街を評価してみました。

あくまでも「Webエンジニア」「単身者」目線での評価軸になっています。 経験ベースなので、だいぶ偏りがあると思いますが参考になれば幸いです。

結論: 渋谷が一番おすすめ

日本の最先端を感じることができて学びの機会が多いです。 人生に一度は渋谷に住むのをオススメします!

錦糸町(東京都墨田区)

  • 居住歴:2年、南口徒歩3分、1R 62,000

エンジニアおすすめ度

☆★★★★(4)

ショッピングには困らない、都心へのアクセスも良好

良いところ

  • 駅前が充実している
    • 娯楽、ショッピング、グルメ何でも揃っている
    • ヨドバシカメラ、書店もあるのでエンジニアにとっても嬉しい
  • 交通の便が良い
    • JR、地下鉄を利用可能
    • 東京駅に近いので新幹線利用者におすすめ
    • 半蔵門線を使って渋谷にも一本で行ける
  • カフェ、コワーキングスペースが多い
    • 近隣の駅に比べると多い方
    • 東京駅には無料のコワーキングスペースもあるので錦糸町なら通える

悪いところ

  • 治安があまり良くない(特に南口は繁華街なので素行の悪い人が多い)
  • 駅前は人が多くて落ち着かない

練馬高野台(東京都練馬区)

  • 居住歴:2年、北口徒歩15分、1K 68,000

エンジニアおすすめ度

☆☆☆★★(2)

リモートワーク中心の人にオススメ

良いところ

  • 池袋へのアクセスが良い
    • 西武池袋線を利用することで池袋へ一本で行ける
    • 西武有楽町線、副都心直通もあるので東京駅付近への通勤も比較的ラク
    • 副都心線直通で渋谷まで一本で行ける
  • 駅が新しいので町並みが綺麗
    • 特に石神井川の桜並木は感動モノ
    • リモートワークの合間に散歩するとリラックスできる
  • 人が少なく落ち着いている
  • 23区の中では家賃は安め

悪いところ

  • 駅前が閑散としている
    • 飲食店が少ない
    • 池袋か石神井公園まで行かなければショッピングできない
    • 近くに書店がない
    • ヤマダ電機が徒歩圏内にあるのが救い
  • カフェが駅前に2,3店ほどしかなく、コワーキングスペースがない
  • 都心に出るには池袋を経由しなければいけない

大宮(埼玉県さいたま市)

  • 居住歴:2年、東口徒歩3分、1K 72,000

エンジニアおすすめ度

☆☆★★★(3)

「通勤時間」より「安さ・便利さ」重視ならおすすめ

良いところ

  • 東京、埼玉、東北方面のアクセスが良い
    • 京浜東北線の終点なので飲み会後に寝過ごす心配がない
    • 横浜までも一本で行ける
  • 駅前が充実している
    • 娯楽、ショッピング、グルメ何でも揃っている
    • ビックカメラ、書店もあるのでエンジニアにとっても嬉しい
  • カフェ、コワーキングスペースが多い
  • 東京に比べると家賃が安い

悪いところ

  • 東京が仕事場の場合、通勤時間がかかる
  • 駅前は人が多くて落ち着かない
  • 東口は居酒屋、歓楽街が多いので住む場所は選んだほうが良い

武蔵浦和(埼玉県さいたま市)

エンジニアおすすめ度

  • 居住歴:3年、徒歩30分、2LDK 92,000 (駐車場8,000円)

☆☆☆☆★(1)

リモートワーク中心で車持ならおすすめ

良いところ

  • 東京に比べて家賃がかなり安い
  • 意外と駅前が充実している
    • おしゃれな飲食店がある
    • カフェ(スタバ、ドトール、サンマルクなど)が多くある
    • 駅直結にホームセンターがある

悪いところ

  • 通勤ラッシュがやばい
    • 東京に出るには埼京線に乗る必要があり朝は地獄
  • 車がないと買い物に不便
    • 近くに大型スーパーがないので車がないと辛い

渋谷(東京都渋谷区)

  • 居住歴:4年、新南口徒歩5分、1K 99,000

エンジニアおすすめ度

★★★★★(5)

とても刺激になるのでエンジニアなら一度は住みたい

良いところ

  • 徒歩圏内で何でも揃う
    • 基本渋谷で完結する
    • 原宿、表参道、代官山、恵比寿にも徒歩で行ける
  • 流行の最先端に触れることが出来る
  • ITの仕事に困らない
    • 特にフリーランスの場合は仕事が山ほどある
  • コワーキングスペースが充実している
    • コワーキングスペースだけでネットワークを構築できる
    • 私はco-ba渋谷を使っていました

悪いところ

  • 家賃がかなり高い
    • 1Kでも10万円近い
  • エリアによっては住みにくい(特に道玄坂、原宿エリアはオススメしない)
  • 安価なスーパーが少ない

三軒茶屋(東京都世田谷区)

  • 居住歴:2年、徒歩15分、1LDK 138,000

エンジニアおすすめ度

☆★★★★(4)

フリーランスが多く意識が高まる街

良いところ

  • 渋谷に近い
    • 自転車、バスでも通える距離
  • カフェ、コワーキングスペースが多い
    • Wifi環境が整っているカフェが多く存在する
    • コワーキングスペースもある
  • 意識の高い人が多く住んでいる
    • 渋谷に通うビジネスマンやフリーランスが多く住んでいる
    • おしゃれなお店が多い

悪いところ

  • 街が騒がしい
    • 大学生が多く騒がしい
    • 居酒屋が多く、夜は治安が悪い場所がある
  • 道が狭い
    • 気を遣って歩く必要がありストレスが溜まる
  • 家賃が高め

辻堂(神奈川県藤沢市)

  • 居住歴:1年、南口徒歩15分、2LDK 102,000

エンジニアおすすめ度

☆☆★★★(3)

都心にあまり出ないならかなりオススメ

良いところ

  • 自然が多い
    • 駅から徒歩で海に行ける
    • 辻堂海浜公園という大きな公園がありランニングや散歩におすすめ
  • ショッピング施設が充実している
    • テラスモールという湘南最大のショッピングモールがある
    • 周辺にも大型ショッピングモールがいくつかある
  • カフェ、コワーキングスペースが充実している

悪いところ

  • 東京に出るのに時間がかかる
    • 東海道線の各駅しか止まらない
    • 通勤ラッシュは避けられない
    • 都内からの終電が早い(23時台)
  • 車がないと不便な場合がある
    • なくても生活できるが生活圏がだいぶ限られる
  • 津波が心配
    • 南口に住むならはハザードマップの確認必須