TableView の実装(7) : hkob の雑記録 (464)

はじめに

hkob の雑記録の第464回目(連続37日目)は、TableView の filter と sorts に対応を検討します。

JSON の再取得

これまで、フィルタなどが未設定だったので、全て null になっていました。このため、データベースで quick_filter, filter, sort を設定して、JSON を再取得しました。該当部分だけ掲載します。property の部分は名前ではなく property_id が登録されているようです。JSON の形態的には Query で利用するものと同じになります。

  "filter": {
    "property": "SPrp",
    "date": {
      "on_or_after": "today"
    }
  },
  "sorts": [
    {
      "property": "{GE|",
      "direction": "ascending"
    }
  ],
  "quick_filters": {
    "MNV~": {
      "status": {
        "equals": [
          "To-do",
          "In progress"
        ]
      }
    }
  },

table_view_spec.rb の修正

上で書いたように filter と sorts については、query を保持するようにします。そこから filter や sort で格納された JSON が取得できればいいと考えています。

        context "when filter and sorts" do
          let(:query) { target.query }

          it { expect(query.class).to eq Query }

          it {
            expect(query.filter).to eq(
              {
                "property" => "SPrp",
                "date" => {
                  "on_or_after" => "today",
                },
              },
            )
          }

          it {
            expect(query.sort).to eq(
              [
                {
                  "property" => "{GE|",
                  "direction" => "ascending",
                },
              ],
            )
          }
        end

view.rb の修正

JSON 内の filter と sorts が存在したら、それらの JSON が含まれる Query が生成されるようにします。両方とも存在せず null の場合には、何も絞り込みも並び順も未設定の Query が生成されます。

  class View
    # @param [String, nil] id
    # @param [String, nil] json
    def initialize(id: nil, json: nil)
      @nc = NotionCache.instance
      @json = json
      @id = @nc.hex_id(id || @json && @json["id"])
      filter = @json["filter"] == "null" ? nil : @json["filter"]
      sorts = @json["sorts"] == "null" ? nil : @json["sorts"]
      @query = Query.new filter: filter, sort: sorts
      configuration = @json["configuration"]
      return unless @json && configuration

      @type = configuration["type"]
      @properties = configuration["properties"].map do |property|
        ViewProperty.create_from_json property["property_name"], property
      end
      return unless configuration["subtasks"]

      @subtasks = Subtasks.new configuration["subtasks"]
    end
    attr_reader :id, :json, :type, :properties, :subtasks, :query

テスト結果確認

実際にここまでの実装を確認してみます。Query を流用することで実装はかなり短くなりました。

NotionRubyMapping::TableView
  find
    when real access
      is expected to be a kind of NotionRubyMapping::TableView
      is expected to eq "32fd8e4e98ab81e88ba9000c227aaf76"
      is expected to eq "table"
      is expected to eq ["Title", "TextTitle", "NumberTitle", "SelectTitle", "MultiSelectTitle", "DateTitle", "UserTitle", (中略) "VerificationTitle", "OwnerTitle", "BlockedByTitle", "BlockingTitle", "SubItemTitle", "ParentTitle"]                                                                                
      when subtasks
        is expected to eq NotionRubyMapping::View::Subtasks
        is expected to eq "parents"
      when filter and sorts
        is expected to eq NotionRubyMapping::Query
        is expected to eq {"date" => {"on_or_after" => "today"}, "property" => "SPrp"}
        is expected to eq [{"direction" => "ascending", "property" => "{GE|"}]
    when dry run
      behaves like dry run
        is expected to eq "#!/bin/sh\ncurl  'https://api.notion.com/v1/views/32fd8e4e98ab81e88ba9000c227aaf76' \\\n  -H 'Notion-Version: 2026-03-11' \\\n  -H 'Authorization: Bearer '\"$NOTION_API_KEY\"''"                                                                                                        

Finished in 0.0052 seconds (files took 0.20802 seconds to load)
10 examples, 0 failures

おわりに

Query a data source には必要なのですが、quick_filter も同じ Query で取り扱った方が綺麗な気がします。これを踏まえて明日対応します。

https://hkob.notion.site/hkob-16dd8e4e98ab807cbe3cf3cc94cdfe0f?pvs=4hkob.notion.site