type="date"なフォームをcapybara+chromeでテストするには

  • type="date"なフォームは現時点ではsafari以外のブラウザはカレンダーっぽい入力に対応している
  • こんな感じになる
    • f:id:willnet:20210412183642p:plain
  • 入力もtype="text"のときとは違うようで、普通にfill_in '日付', with: '2021-01-01'のような入力だと期待通りの日付が入力できない
    • なぜか10101-02-02みたいになってしまう
    • テストが失敗する
  • capybaraはこれを回避するためにjsで日付を埋めることをしている。これは入力がString以外かつto_date?に 対応しているオブジェクトが対象。なのでfill_in '日付', with: Date.new(2021, 1, 1)`のようにしたところテストが通った

Docker環境でRubymineを使う

  • Rubymineはコードジャンプがべんり
  • gemのソースコードにもサッとジャンプできる
  • しかしDockerで開発していると、gemのコードはコンテナの中なのでそのままだとジャンプできない
  • これまではやむを得ずホスト側でbundle installとかしてたけど、設定でコンテナ側のgemを参照できるのだった(当たり前)

やり方

Preferences→Languages & Frameworks→Ruby SDK and Gemsで+を選択、New remoteを選択して次のようにして新しい設定を作成し、それを選択してapplyすればOK(appとしているところは各自のrails用コンテナに読み替えてください)

f:id:willnet:20210223142323p:plain

USキーボード環境で英数キーを⌘+スペースに割り当てた

ずっと左コマンドを単体で押したときに英数、右コマンドを単体で押したときにかなとしていたけど、左コマンドキーを押してすぐキーをタイプするとミスってタブを閉じてしまったりなどすることがよくあった。

我慢して使っていたのだけど、だれかのツイートでコマンドとスペースを利用して切り替えるようにした、というのを見かけてこれ良いのでは?となったのでkarabinerの設定を↓のように変えた。左コマンドだけスペースが必要にしてみた。右コマンドは単体でしか押さないので従来どおり。

~/.config/karabiner/karabiner.json を以下のように編集した

               "rules": [
                    {
                        "description": "右コマンドキーを単体で押したときに、かなキーを送信する",
                        "manipulators": [
                            {
                                "from": {
                                    "key_code": "right_command",
                                    "modifiers": {
                                        "optional": [
                                            "any"
                                        ]
                                    }
                                },
                                "parameters": {
                                    "basic.to_if_held_down_threshold_milliseconds": 100
                                },
                                "to": [
                                    {
                                        "key_code": "right_command",
                                        "lazy": true
                                    }
                                ],
                                "to_if_alone": [
                                    {
                                        "key_code": "japanese_kana"
                                    }
                                ],
                                "to_if_held_down": [
                                    {
                                        "key_code": "right_command"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "左コマンドキーとスペースを押したときに英数キーを送信する",
                        "manipulators": [
                            {
                                "from": {
                                    "key_code": "spacebar",
                                    "modifiers": {
                                        "mandatory": [ "left_command" ]
                                    }
                                },
                                "to": [
                                    {
                                        "key_code": "japanese_eisuu"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    }
                ]
            },

追記

右コマンドキーは単純にかなキーに入れ替えたほうが安定したので、結局上記の右コマンドキー側の設定は削除しました。

家のインターネット環境を安定させた

自宅で作業するのが増えた結果、インターネットが遅くなったり、ルーターとの接続が切れたりするのに気づくことが増えた。ので設定を変更してなんとかしたぞというメモ

前提

  • niftyのv6プラスを利用済み
    • ルータの近くだと20~30Mbpsくらいでる
    • v6プラス以前は1Mbpsとか。ひどい有様だった…
  • 有線は部屋の配置の問題でケーブルをひくのが難しいので無線でやるしかない
  • PCは窓際なので、外の電波に影響を受けている可能性が高そう

やった(やっている)こと

  • 5GHz帯を使う
  • 利用チャンネルを動的に変更するように設定を変更
    • 時間によって接続が不安定になった&&ルーター近くだと安定していたので、外の電波と関係があるのではと推測
  • チャンネルを束ねて高速化する機能をオフにした
    • 有線でも20~30Mbpsしかでないのにチャンネルを束ねる必要はなかった
    • 束ねた結果、外の電波と干渉して接続を失ったのではないかと推測

Railsのbelongs_toによるバリデーションと外部キー制約って重複しているような気がする

表題のとおりなのですが。

class Post < ApplicationRecord
  belongs_to :user
end

↑のように書いたときに、Rails5からは自動でvalidation_presence_of :userとしたのと同じになります。postをバリデーションするときにuserの存在をチェックする必要があるので、userが未ロードであればクエリが発行されます。一度にたくさんのpostを保存するようなケースでN+1が発生して困った経験がある人もいるのではないでしょうか。

./bin/rails g model post user:references のようにした場合は、次のように外部キー制約とbelongs_toが両方定義された状態になりますね。

class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end
class Post < ApplicationRecord
  belongs_to :user
end

しかし、PostからUserへ外部キー制約を貼っていればvalidation_presence_of :userは不要では?という気がします。むしろ無駄にクエリが発行される分マイナスなような気もする。

次のようにすればOKではあるけれど、実際は必須なのにoptional: trueと書かなければいけないなのが大変微妙。

class Post < ApplicationRecord
  belongs_to :user, optional: true
end

と、ここまで書いていて気がついたけど論理削除のようなしくみを採用していた場合は外部キー制約では不十分ですね…とりあえず今回のケースではそれは考慮しないとします…><

このへん、みんなどのように解決しているのでしょうか?コメントほしいです(\( ⁰⊖⁰)/)

  1. 外部キーを使っておらず、belongs_toによるバリデーションを利用している
  2. Railsが生成するデフォルトのように、外部キーとbelongs_toによるバリデーションを両方使っている
  3. 外部キーのみ使用しており、belongs_toによるバリデーションはオフにしている
  4. その他

Rails 6時代のCredentailsをどうやって書くのが一番スマートなのか

Rails6ではcredentials.yml.encが複数の環境で作れるようになりました*1。staging環境などでもCredentialsが使えてべんり!となったのだけどdevelopment環境やtest環境の秘密の文字列はどのようにするべきなのでしょうか。たぶんRails公式ではこういう書き方を想定しているんじゃないかな、と想像します。

secret_token = if Rails.env.development? || Rails.env.test?
                 '開発用の秘密の文字列'
               else
                 Rails.application.credentials.secret_token
               end

もちろんこれでも書けなくはないのだけど、こういうのが色んな場所にあったりするともっといい感じにできないもんかな…、という気持ちになりますね。

stagingと同様にconfig/credentials/development.yml.enc とconfig/credentials/test.yml.enc を作るとRails.application.credentials.secret_tokenだけですべての環境をカバーできるけど、たいていdevelopmentとtestは同じ秘密の文字列を指すのでこれはこれでなんだかな、となる。

そこでググってみたところRails 6 adds support for multi environment credentials – Saeloun Blog という記事では次のようにしているのを見つけました。

  • credentials.yml.enc を開発用(development, test)にする
  • config/credentials/production.yml.enc を別途作る

これだと前述の問題を解決できそう。Rails 5.2時代を経験していると「credentials.yml.encはproduction用途である」という思い込みがあるので初見で面食らう、という点を除けばこれが最適解なような気もします。

みなさんはどんな感じでCredentialsを管理しているか教えてほしいです(\( ⁰⊖⁰)/)。

*1:詳しく知りたい人はこちらを読んでみると良さそう https://gihyo.jp/book/2019/978-4-297-10869-4