はじめに
hkob の雑記録の第279回目は、 NotionRubyMapping で昨日解説した場所プロパティを扱えるようにした件を解説していきます。
テストページ作成
まずはテストページを作成します。Place Property だけを持つデータベースを作成し、1ページ用意しています。

まずは、データソースIDを取得します。

DataSource の確認
データソースを取得します。
ds = DataSource.find "282d8e4e-98ab-804b-b7dc-000bf0ca279e" => NotionRubyMapping::DataSource-282d8e4e98ab804bb7dc000bf0ca279e
Place プロパティを確認します。当然ながら Irregular property type となります。
ds.properties["Place"] /Users/hkob/.local/share/mise/installs/ruby/3.4.6/lib/ruby/gems/3.4.0/gems/notion_ruby_mapping-3.0.0/lib/notion_ruby_mapping/properties/property.rb:125:in 'NotionRubyMapping::Property.create_from_json': Irregular property type: place (StandardError) from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/lib/ruby/gems/3.4.0/gems/notion_ruby_mapping-3.0.0/lib/notion_ruby_mapping/controllers/property_cache.rb:20:in 'NotionRubyMapping::PropertyCache#[]' from (irb):3:in '<main>' from <internal:kernel>:168:in 'Kernel#loop' from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/lib/ruby/gems/3.4.0/gems/irb-1.15.2/exe/irb:9:in '<top (required)>' from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/bin/irb:25:in 'Kernel#load' from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/bin/irb:25:in '<main>'
JSON を確認してみます。設定項目もないので、特に値も何もありません。
ds.json
=>
{"object" => "data_source",
"id" => "282d8e4e-98ab-804b-b7dc-000bf0ca279e",
(中略)
"properties" =>
{"Place" =>
{"id" => "AmdZ",
"name" => "Place",
"description" => nil,
"type" => "place",
"place" => {}},
Page の確認
同様にページプロパティの確認のために、ページデータも取得します。
page = Page.find "https://www.notion.so/hkob/TMCIT-Shinagawa-282d8e4e98ab8048bd3ecd8a933392c7?v=282d8e4e98ab801e873c000c24b95e43&source=copy_link" => NotionRubyMapping::Page-282d8e4e98ab8048bd3ecd8a933392c7
当然ながらこちらも Place プロパティにアクセスするとエラーになります。
page.properties["Place"] /Users/hkob/.local/share/mise/installs/ruby/3.4.6/lib/ruby/gems/3.4.0/gems/notion_ruby_mapping-3.0.0/lib/notion_ruby_mapping/properties/property.rb:125:in 'NotionRubyMapping::Property.create_from_json': Irregular property type: place (StandardError) from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/lib/ruby/gems/3.4.0/gems/notion_ruby_mapping-3.0.0/lib/notion_ruby_mapping/controllers/property_cache.rb:20:in 'NotionRubyMapping::PropertyCache#[]' from (irb):6:in '<main>' from <internal:kernel>:168:in 'Kernel#loop' from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/lib/ruby/gems/3.4.0/gems/irb-1.15.2/exe/irb:9:in '<top (required)>' from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/bin/irb:25:in 'Kernel#load' from /Users/hkob/.local/share/mise/installs/ruby/3.4.6/bin/irb:25:in '<main>'
こちらも同じように JSON を確認してみます。こちらは place には nil が入っていました。
page.json
=>
{"object" => "page",
"id" => "282d8e4e-98ab-8048-bd3e-cd8a933392c7",
(中略)
"properties" =>
{"Place" => {"id" => "AmdZ", "type" => "place", "place" => nil},
テストデータの準備
まず、DataSource の Property 表現である Property object を用意します。 spec/fixtures/place_property_object.json を用意しました。
{ "id": "AmdZ", "name": "Place", "type": "place", "place": {} }
Page property は API で取得できるので、 retrieve_property_place.sh を用意しました。
curl 'https://api.notion.com/v1/pages/282d8e4e98ab8048bd3ecd8a933392c7/properties/AmdZ' \ -H 'Notion-Version: 2025-09-03' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"''
make すると retrieve_property_place.json を取得できました。最近は、request_id が返ってくるのですね。
{ "object": "property_item", "type": "place", "id": "AmdZ", "place": null, "request_id": "3ebb46a3-f127-4ff7-9d20-050afd32fd4d" }
テストの作成
テストである spec/notion_ruby_mapping/place_property_spec.rb は button_property_spec.rb を書き換えて作成しました。
# frozen_string_literal: true module NotionRubyMapping RSpec.describe PlaceProperty do tc = TestConnection.instance let(:no_content_json) { {"id" => "AmdZ"} } let(:place_page_id) { TestConnection::PLACE_PAGE_ID } let(:property_cache_first) { PropertyCache.new base_type: "page", page_id: place_page_id } correct = {"Place" => {"type" => "place", "place" => nil}} context "Database property" do context "created from json" do let(:target) { Property.create_from_json "Place", tc.read_json("place_property_object"), "database" } it_behaves_like "has name as", "Place" it_behaves_like "will not update" it_behaves_like "assert different property", :property_values_json it_behaves_like "update property schema json", {} it_behaves_like "raw json", "place", {} end end context "DataSource property" do context "created from json" do let(:target) { Property.create_from_json "Place", tc.read_json("place_property_object"), "data_source" } it_behaves_like "has name as", "Place" it_behaves_like "will not update" it_behaves_like "assert different property", :property_values_json it_behaves_like "update property schema json", {} it_behaves_like "raw json", "place", {} end end context "Page property" do context "created from json" do let(:target) { Property.create_from_json "Place", tc.read_json("retrieve_property_place") } it_behaves_like "has name as", "Place" it_behaves_like "will not update" it_behaves_like "property values json", correct it_behaves_like "assert different property", :update_property_schema_json it_behaves_like "assert different property", :property_schema_json end context "created from json (no content)" do let(:target) { Property.create_from_json "Place", no_content_json, "page", property_cache_first } it_behaves_like "has name as", "Place" it_behaves_like "will not update" it { expect(target.contents?).to be_falsey } it_behaves_like "assert different property", :update_property_schema_json # hook property_values_json / created_by to retrieve a property item it_behaves_like "property values json", correct end end end end
ここで、テスト内で Property 読み込みの API 呼び出しを実行するので、WebMock による stub を追加しておきます。API 呼び出しが行われると、上で取得しておいた retrieve_property_place.json をこっそり返す処理をしています。
def retrieve_property generate_stubs_sub :get, __method__, :page_property_path, { button: [[BUTTON_PAGE_ID, "%7CyVi"], 200], checkbox: [[DB_FIRST_PAGE_ID, "Lbi%5D"], 200], created_by: [[DB_FIRST_PAGE_ID, "eR%3D~"], 200], created_time: [[DB_FIRST_PAGE_ID, "WsEj"], 200], date: [[DB_FIRST_PAGE_ID, "SPrp"], 200], email: [[DB_FIRST_PAGE_ID, "p%7Ci%3F"], 200], files_external: [[DB_FIRST_PAGE_ID, "qEdK"], 200], files_internal: [[DB_SECOND_PAGE_ID, "qEdK"], 200], formula: [[DB_FIRST_PAGE_ID, "%5D~iZ"], 200], last_edited_by: [[DB_FIRST_PAGE_ID, "LQGa"], 200], last_edited_time: [[DB_FIRST_PAGE_ID, "X%3E%40X"], 200], multi_select: [[DB_FIRST_PAGE_ID, "Kjx%7D"], 200], number: [[DB_FIRST_PAGE_ID, "swq%5C"], 200], people: [[DB_FIRST_PAGE_ID, "_x%3E%3D"], 200], place: [[PLACE_PAGE_ID, "AmdZ"], 200], phone_number: [[DB_FIRST_PAGE_ID, "%7CNHO"], 200], relation: [[DB_FIRST_PAGE_ID, "%3CnJT"], 200], relation_with_many_relations: [[DB_MANY_CHILDREN_PAGE_ID, "%60%5B%3E%7B"], 200], rich_text: [[DB_FIRST_PAGE_ID, "flUp"], 200], rich_text_limit_5: [[DB_SECOND_PAGE_ID, "flUp?page_size=5"], 200], rich_text_next_5: [[DB_SECOND_PAGE_ID, "flUp?page_size=5&start_cursor=PLuaRX"], 200], rich_text_last_5: [[DB_SECOND_PAGE_ID, "flUp?page_size=5&start_cursor=xQVa1H"], 200], rollup: [[DB_FIRST_PAGE_ID, "STe_"], 200], select: [[DB_FIRST_PAGE_ID, "zE%7C%3F"], 200], status: [[STATUS_PAGE_ID, "Qy~%3E"], 200], title: [[DB_FIRST_PAGE_ID, "title"], 200], title_top: [[TOP_PAGE_ID, "title"], 200], unique_id: [[DB_FIRST_PAGE_ID, "%7BGE%7C"], 200], verification: [[WIKI_PAGE_ID, "verification"], 200], url: [[DB_FIRST_PAGE_ID, "tvis"], 200], } end
実装の追加
実装である lib/notion_ruby_mapping/place_property.rb もほぼ同様に作成しました。
# frozen_string_literal: true module NotionRubyMapping # Button property class PlaceProperty < Property TYPE = "place" ### Public announced methods ## Common methods # @return [Boolean, Hash, nil] def place @json end # @param [String, Symbol] name Property name # @param [Boolean, Hash] json def initialize(name, will_update: false, base_type: "page", property_id: nil, property_cache: nil, json: nil) super name, will_update: will_update, base_type: base_type, property_id: property_id, property_cache: property_cache @json = json end ## Page property only methods # @return [Hash] def property_values_json assert_page_property __method__ {@name => {"place" => @json, "type" => "place"}} end end end
このファイルを require するように notion_ruby_mapping.rb のプロパティに追加しています。
properties: %w[property checkbox_property multi_property created_by_property date_base_property created_time_property date_property email_property files_property formula_property last_edited_by_property last_edited_time_property multi_select_property number_property people_property phone_number_property relation_property text_property rich_text_property rollup_property select_property status_property title_property unique_id_property url_property button_property verification_property place_property],
あとは、親クラスの Property におけるクラス振り分けを記載すればいいはずです。type が place の場合には、子クラスである PlaceProperty が選択できるようにします。
klass = {
button: ButtonProperty,
checkbox: CheckboxProperty,
created_time: CreatedTimeProperty,
date: DateProperty,
formula: FormulaProperty,
last_edited_time: LastEditedTimeProperty,
rollup: RollupProperty,
email: EmailProperty,
files: FilesProperty,
created_by: CreatedByProperty,
last_edited_by: LastEditedByProperty,
multi_select: MultiSelectProperty,
relation: RelationProperty,
number: NumberProperty,
people: PeopleProperty,
phone_number: PhoneNumberProperty,
place: PlaceProperty,
select: SelectProperty,
status: StatusProperty,
title: TitleProperty,
rich_text: RichTextProperty,
unique_id: UniqueIdProperty,
url: UrlProperty,
verification: VerificationProperty,
}[type.to_sym]
raise StandardError, "Irregular property type: #{type}" unless klass
テスト結果確認
ここまで記載して、テストは無事に成功しました。
> be guard 20:20:04 - INFO - Guard::RSpec is running 20:20:04 - INFO - Guard is now watching at '/Users/hkob/Library/CloudStorage/Dropbox/ruby/notion_ruby_mapping' 20:20:20 - INFO - Running: spec/notion_ruby_mapping/properties/place_property_spec.rb NotionRubyMapping::PlaceProperty Database property created from json behaves like has name as has name as Place behaves like will not update does not update behaves like assert different property property_values_json behaves like update property schema json is expected to eq {} behaves like raw json is expected to eq {} DataSource property created from json behaves like has name as has name as Place behaves like will not update does not update behaves like assert different property property_values_json behaves like update property schema json is expected to eq {} behaves like raw json is expected to eq {} Page property created from json behaves like has name as has name as Place behaves like will not update does not update behaves like property values json is expected to eq {"Place" => {"place" => nil, "type" => "place"}} behaves like assert different property update_property_schema_json behaves like assert different property property_schema_json created from json (no content) is expected to be falsey behaves like has name as has name as Place behaves like will not update does not update behaves like assert different property update_property_schema_json behaves like property values json is expected to eq {"Place" => {"place" => nil, "type" => "place"}} Finished in 0.01158 seconds (files took 0.44386 seconds to load) 20 examples, 0 failures
NotionRubyMapping のアップデート
この変更を GitHub にコミットし、rake release して v3.0.1 をリリースしました。
X にもポストしています。
I have released NotionRubyMapping v3.0.1. It now supports the Place Property which was made public yesterday, ensuring that pages using this property no longer produce errors.#Notion #NotionRubyMappinghttps://t.co/4ZIrF0xb0a
— hkob|Notion Ambassador (@hkob) 2025年10月4日
おわりに
とりあえずこれで場所プロパティを使ったページにアクセスしてもエラーにならなくなりました。特に API から利用はできないのですが、JSON として type が返ってくるものについては対応しないといけないので、これからも迅速に対応したいと思います。