前人未踏の領域へ WEB・インフラ・プログラミング全般編

フロントエンド、バックエンド、インフラ、言語など、アプリ開発、IOT以外の記録

rbenv: Ruby3.2インストールエラー

内容

rbenv でruby 3.2.2をインストールしようとしたら以下のエラーが発生した。

$ rbenv install 3.2.2
To follow progress, use 'tail -f /tmp/ruby-build.20231021091520.5507.log' or pass --verbose
Downloading ruby-3.2.2.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz
Installing ruby-3.2.2...

BUILD FAILED (Ubuntu 18.04 using ruby-build 20230717-11-g4d4678b)

Inspect or clean up the working tree at /tmp/ruby-build.20231021091520.5507.wUPdqj
Results logged to /tmp/ruby-build.20231021091520.5507.log

Last 10 log lines:
make[1]: Leaving directory '/tmp/ruby-build.20231021091520.5507.wUPdqj/ruby-3.2.2'
Generating RDoc documentation
/tmp/ruby-build.20231021091520.5507.wUPdqj/ruby-3.2.2/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych

run with --debug for full backtrace
uncommon.mk:597: recipe for target 'rdoc' failed
make: *** [rdoc] Error 1

対応

必要なライブラリをインストール

$ sudo apt install libyaml-dev libffi-dev

参考

mseeeen.msen.jp

Rails : bundle updateの前にdry-runしたい

課題

bundle updateコマンドを叩いてライブラリを更新したらエラーで動かなくなったので少しずつ進めることに。
じゃあ少しずつ進めるために、どのライブラリに新しいバージョンがあるのかを知るにはどうすればよいか。

対応

bundle outdated を使うと古くなったライブラリを一覧で表示してくれるのでこちらを利用する

$ bundle outdated
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies..............................................

Gem                       Current   Latest    Requested        Groups
administrate              0.16.0    0.19.0    >= 0             default
airbrussh                 1.4.0     1.4.2
bcrypt                    3.1.16    3.1.19    ~> 3.1.7         default
bootsnap                  1.7.3     1.16.0    >= 1.1.0         default
bugsnag                   6.19.0    6.26.0    ~> 6.12          default
capistrano                3.16.0    3.17.3    ~> 3.16          development
以下略

かなりの量が出てきた。オプションなしだと実際には bundle update では更新されないものも表示されるので--strictオプションをつけ、Gemfileの要件で許可されているライブラリだけをリストアップする。--only-explicit もつけて依存関係は省略してGemfileに記載のあるものだけにする。

$ bundle outdated --strict --only-explicit
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...............................................

Gem                       Current   Latest    Requested  Groups
active_hash               3.1.0     3.2.0     >= 0       default
active_model_serializers  0.10.12   0.10.13   >= 0       default
activerecord-import       1.0.8     1.4.1     >= 0       default
administrate              0.16.0    0.19.0    >= 0       default
airbrussh                 1.4.0     1.4.2
bcrypt                    3.1.16    3.1.19    ~> 3.1.7   default
bootsnap                  1.7.3     1.16.0    >= 1.1.0   default
bugsnag                   6.19.0    6.26.0    ~> 6.12    default
以下略

これで目的のものが得られた。--strictとの違いがよく分からないけど --update-strict もつけているといいかもしれない。

この他にもbundle outdated --help を見ると他にも使えそうなオプションがあり、bundle updateのオプションと関連しているものもあったので色々試してみると良さそうだ。

実際にやってみる

bundle outdatedを使って段階的なアプデをしてみよう。

まず--patchを使ってpatchがあるものだけチェック

$ bundle outdated --patch  --strict 
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies....

Gem                       Current   Latest    Requested  Groups
active_hash               3.1.0     3.1.1     >= 0       default
active_model_serializers  0.10.12   0.10.13   >= 0       default
airbrussh                 1.4.0     1.4.2
bcrypt                    3.1.16    3.1.19    ~> 3.1.7   default
以下略

次に実際に bundle update--patchオプションをつけてパッチバージョンだけ上げる

$ bundle update --patch  --strict 
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Using rack 2.2.8 (was 2.2.6.4)
Using nio4r 2.5.9 (was 2.5.8)
Using thor 1.2.2 (was 1.2.1)
$ bundle outdated --patch --strict 
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...

Bundle up to date!

無事パッチだけ更新されたのでここでSPECの実行、軽い動作チェックを挟つつ、--minor --major と更新していけば問題が起きても比較的早く解決できるだろう。

参考

stackoverflow.com

Rails: "7月15日".to_date

内容

とあるエラー調査をしていたところ、入力された日付とは異なる日付で取り込まれている問題が発生していた。

入力されたデータは 7月15日 。指定した日付フォーマットとは異なる、何年かも分からない日本語書式である。 これを受け取ったコードではだいたい以下のような感じで書いてあった。

d = '7月15日'
I18n.l(d.to_date, format: :system)

入力を疑うことなくDate型に変換しようとしてるのか。そんなことできるのね。まあそれはいいとして、d.to_dateの結果をRailsコンソールで確認したところ、以下のような結果が得られた

irb(main):008:0 > '7月15日'.to_date
=> Thu, 15 Jun 2023

Jun って6月じゃね? ActiveSupportto_dateを見ると以下のようになっている。

  def to_date
    ::Date.parse(self, false) unless blank?
  end
irb(main):011:0> Date.parse('7月15日')
=> Thu, 15 Jun 2023

うむ、なるほど...。ちなみに 7月31日だとinvalid dateでエラーになる。なんなら全部エラーにしてほしかった。

感想

ググれば出てくるようなRubyRails界隈では有名な話なのだろう(← ググれよ) そもそもなんで漢字を受け付けちゃうのかな。
使ってるライブラリのバージョンが古いので最新バージョンではうまく処理してくれたりするんだろうか。

Rails: 条件付きfind

内容

特定のIDでテーブルからfind()を使ってレコード取得したいが、ついでに条件も指定したい。

対応

Whereを先に書いて、最後にfindをつける。 仮にBooksとテーブルがあり、statusactiveなものだけ対象にしたい場合は以下のようになる。

book = Books.where(status: 'active').find(params[id])

参考

api.rubyonrails.org

Stripe: API実行レシピ

RailsコンソールおよびRails内でコピペして使う用の実例サンプル集。

カスタマー

カスタマーを取得する
cus = Stripe::Customer.retrieve("cus_XxwqzgXcn1XXsk")
サブスクリプション付き
cus = Stripe::Customer.retrieve("cus_XxwqzgXcn1XXsk", {expand:'subscriptions'})

サブスクリプション

カスタマーに紐づくサブスクリプションを1件取得する
sub = Stripe::Subscription.retrieve(cus.subscriptions.data[0].id)
サブスクリプションインボイス付きで1件取得する
sub = Stripe::Subscription.retrieve({id:sub.id ,expand: ['latest_invoice']})
sub.latest_invoice でインボイスデータが取得できる
サブスクリプションインボイスとPaymentIntent付きで1件取得する
sub = Stripe::Subscription.retrieve({id:sub.id ,expand: ['latest_invoice.payment_intent']})
sub.latest_invoice.payment_intentでPaymentIndentが取得できる
カスタマーに紐づくサブスクリプション一覧を取得する
subs = Stripe::Subscription.list({customer: cus.id)
カスタマーの特定の商品に紐づく一覧を取得する
subs = Stripe::Subscription.list( { customer: cus.id, 
           price: 'price_1H860RDmZZkQvLJisnZXJvi' } )

インボイス

サブスクリプションに紐づく最新のインボイスを取得する
invoice = Stripe::Invoice.retrieve(sub.latest_invoice)

PaymentIntent

インボイスに紐づくPaymentIntentを取得する
pi = Stripe::PaymentIntent.retrieve(invoice.payment_intent)
PaymentMethodをPaymentIntentに紐づける

支払いに失敗したPaymentIntentに新しい支払い方法を紐づける場合などで使用。statusがrequires_confirmation になるので別途confirmが必要。subscription.statusincompleteだとエラー

pi = Stripe::PaymentIntent.update(pi.id, {payment_method: cus.invoice_settings.default_payment_method })
PaymentMethodをPaymentIntentに紐づつつConfirmする

支払いに失敗したPaymentIntentに新しい支払い方法でcomfirmする。subscription.statusincompleteだとエラー。

pi = Stripe::PaymentIntent.confirm(pi.id, {payment_method: cus.invoice_settings.default_payment_method })
顧客ごとの次回請求分のインボイスを取得する

次回の請求がない場合にはエラーになるので注意

Stripe::Invoice.upcoming({customer: "cus_XxwqzgXcn1XXsk" })

Apple Silicon版のMacで古いHomebrewを操作する

課題

M1 Macを購入。古いMacからデータを移行したものの、Apple Silicon版の M1 MacではHomebrewのインストール先が /opt/homebrew に変更になっている。旧MacでインストールしたHomebrew内のライブラリにアクセスするにはどうすればよいか。

対応

単にbrewコマンドを実行すると /opt/homebrew/bin/brew が実行される 古い方のbrew コマンドは /usr/local/bin/brew にあるので、こちらを直接叩く

$ /usr/local/bin/brew list
==> Formulae
adns            gmp         libgpg-error        nghttp2         repo
aom         gnupg           libidn2         nkf         rtmpdump
autoconf        gnutls          libksba         node            rubberband
以下略

古い方はRossetaによって動作していると思われるため、 ものによってはインストールし直した方がいいかもしれない。

$ /usr/local/bin/brew uninstall nginx
$ /brew install nginx

一瞬詰んだかと思ったけど落ち着いて対応。

Stripe:任意のWebhookにイベントを再送する

課題

ローカル環境にて、StripeのWebhookが発生する処理をWebhookを無効化している状態で実行してしまった。 webhookが動作してないと必要なデータが更新されない。どうすればよいか。

対応

15日間以内ならイベント詳細画面から「Webhook の試行」再送ボタンで再送ができる。
15日を超えてしまっているか、対象となるwebhookが施行一覧にない場合はCLIでコマンドを実行する必要がある

  1. (前提)webhookを登録・有効化して受け取れるようにしておく。CLIも使える状態であること
  2. 発生したはずの処理(定期支払とか)の画面から「イベントとログ」を見る。アクティビティの一覧があるので、どれかを選択して「イベントの詳細を表示」をクリック
  3. イベント詳細画面のURLまたは画面右上からevent_id (evt_xxxx のやつ)が得られる。
  4. Webhook一覧から対象のエンドポイントをクリック。URLからwebhook_id(we_xxxxxx)を得られる
  5. コンソールを開き eventのresendコマンドを実行する。--webhook-endpoint オプションを付けて対象のwebhookに通知されるようにする
stripe events resend evt_1IBf1YDm6Ck62QvL7XX3THT7 --webhook-endpoint=we_1HQ6sXXm6Ck62QvLBXTGoBEV

レスポンスのJSONが表示されれば成功。

/* Responsive: yes */