開発中のプロジェクトでrails6 -> rails7にした
基本は
https://railsguides.jp/upgrading_ruby_on_rails.html
の手順を守ればOKですがdocker 環境のせいかbundle update
が一晩かけても終わらなかったので、Gemfile.lock
を削除してGemfile
のrailsのバージョンを書き換えてbundle install
しました。
変更点はこれだけです。
gem 'rails', '~> 6.1.4', '>= 6.1.4.1' gem 'rails', '~> 7.0.2', '>= 7.0.2.2' gem 'rails-i18n', '~> 6.0.0' gem 'rails-i18n', '~> 7.0.0'
webpackerはとりあえず使い続ける選択をしたので大きな問題はありませんでした。
ただ、rspecでsessionをmockしているところが動かなくなってました
allow_any_instance_of(ActionDispatch::Request) .to receive(:session) .and_return({id: 1})
理由はちゃんとわかってないですが、下記のようなヘルパーを作って対処しました
def initialize_mock_session mock_session = allow_any_instance_of(ActionDispatch::Request::Session) # おまじない。↓のエラーの対策 # Please stub a default value first if message might be received with other args as well. mock_session.to receive(:[]).and_call_original mock_session end # 利用方法 mock_session.to receive(:[]).with(:id).and_return(1)
rails seedを冪等性にする。sanitizeがデフォルトで許可しているタグ
rails 6.1 ruby 3.0
seedを冪等性にする
docker compose up
などでbin/rails db:seedを実行する環境などで何度実行されても同じ結果にしたいと思いました。
ActiveRecord::Base.connection.disable_referential_integrity do ActiveRecord::Base.connection.execute("TRUNCATE users") User.create(name: "user1") end
TRUNCATEでidも元に戻るので、create時に指定しなくても大丈夫です。
プロジェクトのみんなからはそんなに好意的な意見は聞かれなかったので、とりあえずではあります。
docker起動時のコマンドを改善した方がいい気はする。
find_or_create_byは?
db:seedの後で、どこかのカラムを変更し、もう一度db:seedするときに、idを指定するとduplicateになり、指定しないと似たようなレコードがもう1レコードできてしまいます。
sanitizeがデフォルトで許可しているタグ
多分この辺です。ガイドにも書いてない。
htmlをそのまま表示しなければいけない時にscriptタグとかは許可したくない時に使えます。
rawよりは安全です。
BUFFALOのルータWSR-5400AX6でVPN(L2TP/IPsec)に繋がるようになった
昔に買ったWZR-450HP(発売時期: 2012年6月)は繋がったんですが、逆に新しい方がつながりませんでした。
結果としては、二つの設定を見比べると古い方はPPPoEでインターネットに接続していて、 新しい方はそうじゃないようでした。 じゃあ何で繋がってたかはよくわかってないです。IPoEですかね?
色々試した結果それがわかったので、新しい方のルータでも無理やりPPPoEで繋いで見たところ つながりました。
これがその設定です。
最初は「インターネット@スタートを行う」にチェックが入ってるんですが、それを上記のように変えました。
古いルータでは「PPPoEクライアント機能を使用する」の項目はありますが、「インターネット@スタートを行う」にチェックが入っていても VPNは繋がりました。
後、新しい方のルータでやったことは、ルータモードみたいなのをautoから常にONみたいなのにしました。
Android Firestore: grpc-javaのバグ
FlutterのプロジェクトでGoogle Playが入ってないエミュレータかつAndroid11で例外が発生するということをメンバーが見つけてくれました。
こんな感じのスタックトレースになってます。
W/GooglePlayServicesUtil( 3931): com.example.debug requires the Google Play Store, but it is missing. E/GooglePlayServicesUtil( 3931): GooglePlayServices not available due to error 9 W/Firestore( 3931): (23.0.3) [GrpcCallProvider]: Failed to update ssl context: com.google.android.gms.common.GooglePlayServicesNotAvailableException I/.learning.debu( 3931): NativeAlloc concurrent copying GC freed 68025(3478KB) AllocSpace objects, 17(532KB) LOS objects, 49% free, 3278KB/6556KB, paused 2.569ms total 126.063ms W/.learning.debu( 3931): Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B (greylist-max-q,core-platform-api, reflection, denied) W/.learning.debu( 3931): Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B (greylist-max-q, reflection, denied) E/AndroidRuntime( 3931): FATAL EXCEPTION: grpc-okhttp-0 E/AndroidRuntime( 3931): Process: com.example.debug, PID: 3931 E/AndroidRuntime( 3931): java.lang.AssertionError: Method getAlpnSelectedProtocol not supported for object SSL socket over Socket[address=firestore.googleapis.com/172.217.31.138,port=443,localPort=53942] E/AndroidRuntime( 3931): at io.grpc.okhttp.internal.OptionalMethod.invoke(OptionalMethod.java:114) E/AndroidRuntime( 3931): at io.grpc.okhttp.internal.OptionalMethod.invokeWithoutCheckedException(OptionalMethod.java:135) E/AndroidRuntime( 3931): at io.grpc.okhttp.OkHttpProtocolNegotiator$AndroidNegotiator.getSelectedProtocol(OkHttpProtocolNegotiator.java:183) E/AndroidRuntime( 3931): at io.grpc.okhttp.OkHttpProtocolNegotiator$AndroidNegotiator.negotiate(OkHttpProtocolNegotiator.java:145) E/AndroidRuntime( 3931): at io.grpc.okhttp.OkHttpTlsUpgrader.upgrade(OkHttpTlsUpgrader.java:63) E/AndroidRuntime( 3931): at io.grpc.okhttp.OkHttpClientTransport$4.run(OkHttpClientTransport.java:571) E/AndroidRuntime( 3931): at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) E/AndroidRuntime( 3931): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/AndroidRuntime( 3931): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/AndroidRuntime( 3931): at java.lang.Thread.run(Thread.java:923) I/Process ( 3931): Sending signal. PID: 3931 SIG: 9 Lost connection to device. Exited (sigterm)
playの入ってないエミュレータでもAndroid10なら例外は発生しませんでした。
リリースの必須要件にplayの定期購入があるので、気にしなくても大丈夫だと思いますが、 念の為調べました。
getAlpnSelectedProtocolはAndroid 11 からブロック対象
https://developer.android.com/about/versions/11/non-sdk-11?hl=ja
このメソッドがio.grpc.okhttpというパッケージで呼び出されているのが主な原因のようです。
ただ、playが入っているAndroid11でも例外が発生してもよさそう。
ログに出ているGrpcCallProviderとは
どうやらこの辺りの処理のようです。
firebase-android-sdk/GrpcCallProvider.java at ac3276ce7d5f5181b1c419731495eb88a98537af · firebase/firebase-android-sdk · GitHub
ここで呼び出されているinstallIfNeededというメソッドは下記で説明があります。
セキュリティ プロバイダを更新して SSL エクスプロイトから保護する | Android デベロッパー | Android Developers
ここだけ読んでも良くわかりませんが、どうやらSSLの強度を上げてくれるものっぽいですね。
grpc-java側でもOkHttpTlsUpgraderというクラスがありますが、 firebase sdk側の処理が失敗した時だけ動くんだと予想できます。
その辺りの詳細は調べ切れてませんが、下記のissueを辿っていけば grpc-javaの新しいバージョンで 新しいメソッドのgetApplicationProtocolが呼ばれるような修正が入っていることがわかります。 Crash due to use of getAlpnSelectedProtocol on Android 11 · Issue #7519 · grpc/grpc-java · GitHub
これに伴って、firebase sdk側もアップデートされてますので、 それを利用するようにすればOKなはずです。
reduxの学習と気づいたこと
https://github.com/na8esin/react-redux-practice
今日の時点では、下記が終わったところ
https://redux.js.org/tutorials/essentials/part-7-rtk-query-basics
最近は、 reduxの評判もあまり良くないので、学習に一旦区切りをつけます。
また、typescriptで書かれてないので、書き換えながらやってますが下記のサイトが便利
https://react-typescript-cheatsheet.netlify.app/
noImplicitAnyにしている人は上を見ながら型指定ができます。
それとチュートリアルをやってる時に気になったことがあります。
ソースを動かすときにapiはmswを使うんですが、それを呼び出すときのコードがこんな感じです。 https://github.com/reduxjs/redux-essentials-example-app/blob/master/src/api/client.js
このソースのコメントで下記のリンクが載っています。
Replace axios with a simple custom fetch wrapper
これを読むとaxiosもなるべく使わない方向で行こうかなという気持ちになりました。