Drop item url and use change for the sources migration
Nothing sets or shows an item's url; a synced kind can keep a link in its
own item table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LG4iASZnHb1yEM1JAASiWn
diff --git a/db/migrate/004_add_list_sources.rb b/db/migrate/004_add_list_sources.rb
index 4984a96..2a09109 100644
--- a/db/migrate/004_add_list_sources.rb
+++ b/db/migrate/004_add_list_sources.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
Sequel.migration do
- up do
+ change do
# Every list gets its items from exactly one source. Lists before this
# were made from the textarea, so they default to the text source. A
# kind that needs configuring gets its own table keyed by list_id; Text
@@ -11,24 +11,11 @@ Sequel.migration do
add_column :synced_at, DateTime
end
- # Items keep only what any source has. How a kind recognizes its items
- # across syncs, and anything else it knows about them, lives in its own
- # table keyed by item_id; Text recognizes items by name.
+ # Items keep only what any source has. How a synced kind recognizes its
+ # items across syncs, and anything else it knows about them, lives in its
+ # own table keyed by item_id.
alter_table(:items) do
- add_column :url, String
add_column :archived_at, DateTime
end
end
-
- down do
- alter_table(:items) do
- drop_column :url
- drop_column :archived_at
- end
-
- alter_table(:lists) do
- drop_column :source_kind
- drop_column :synced_at
- end
- end
end
diff --git a/lib/rank_king/sources.rb b/lib/rank_king/sources.rb
index cd08a41..9909ef2 100644
--- a/lib/rank_king/sources.rb
+++ b/lib/rank_king/sources.rb
@@ -4,10 +4,10 @@ module RankKing
module Sources
# What every source produces: one entry per item currently in the source.
# key is how the source recognizes the same item across syncs (see
- # items_by_key); name and url are the item fields any source has.
+ # items_by_key); name is the item field any source has.
# Signed in sig/rank_king/sources.rbs: a Data class.
# @rbs skip
- Entry = Data.define(:key, :name, :url)
+ Entry = Data.define(:key, :name)
end
end
diff --git a/lib/rank_king/sync.rb b/lib/rank_king/sync.rb
index 3c73739..ea6b9e5 100644
--- a/lib/rank_king/sync.rb
+++ b/lib/rank_king/sync.rb
@@ -19,7 +19,7 @@ module RankKing
added = restored = 0
entries.each do |entry|
- attrs = { name: entry.name, url: entry.url, archived_at: nil }
+ attrs = { name: entry.name, archived_at: nil }
if (item = existing.delete(entry.key))
restored += 1 if item.archived_at
item.update(**attrs)
diff --git a/sig/rank_king/models.rbs b/sig/rank_king/models.rbs
index 94c9ef4..d203e49 100644
--- a/sig/rank_king/models.rbs
+++ b/sig/rank_king/models.rbs
@@ -25,7 +25,6 @@ module RankKing
def name: () -> String
def list_id: () -> Integer
def list: () -> List
- def url: () -> String?
def archived_at: () -> Time?
end
diff --git a/sig/rank_king/sources.rbs b/sig/rank_king/sources.rbs
index 1f3a94a..02f720e 100644
--- a/sig/rank_king/sources.rbs
+++ b/sig/rank_king/sources.rbs
@@ -6,9 +6,8 @@ module RankKing
class Entry
attr_reader key: String
attr_reader name: String
- attr_reader url: String?
- def self.new: (key: String, name: String, url: String?) -> instance
+ def self.new: (key: String, name: String) -> instance
end
# A synced source instance, for one list.
diff --git a/test/test_sync.rb b/test/test_sync.rb
index a9df977..20acff9 100644
--- a/test/test_sync.rb
+++ b/test/test_sync.rb
@@ -9,19 +9,20 @@ require_relative "../lib/rank_king/sync"
class TestSync < Minitest::Test
include RankKing
- # A synced source that recognizes its items by URL, standing in for a
- # kind that keeps its keys in its own table.
+ # A synced source that keeps each item's key in memory, standing in for a
+ # kind that keeps its keys in its own table keyed by item_id.
class FakeSource
attr_reader :calls
- def initialize(list)
- @list = list
+ def initialize
+ @keys = {}
@calls = []
end
- def items_by_key = RankKing::Item.where(list_id: @list.id).exclude(url: nil).to_hash(:url)
+ def items_by_key = @keys.transform_values {|id| RankKing::Item[id] }
def saved(item, entry)
+ @keys[entry.key] = item.id
@calls << [item.id, entry.key]
end
end
@@ -35,7 +36,7 @@ class TestSync < Minitest::Test
user = User.create(login: "alpha@example.com")
@list = List.create(name: "Videos", user_id: user.id, source_kind: "Fake")
- @source = FakeSource.new(@list)
+ @source = FakeSource.new
end
def test_adds_new_entries
@@ -52,17 +53,17 @@ class TestSync < Minitest::Test
assert_equal 1, summary.archived
assert_equal %w[a], names
- refute_nil Item.first(url: "https://example.com/b").archived_at
+ refute_nil Item.first(name: "b").archived_at
end
def test_restores_entries_that_come_back
sync("a", "b")
- b = Item.first(url: "https://example.com/b")
+ b = Item.first(name: "b")
sync("a")
summary = sync("a", "b")
assert_equal 1, summary.restored
- assert_equal b.id, Item.first(url: "https://example.com/b").id
+ assert_equal [b.id], Item.where(name: "b").map(:id)
assert_equal %w[a b], names
end
@@ -72,14 +73,13 @@ class TestSync < Minitest::Test
Sync.call(@list, [entry("a", name: "Renamed")], source: @source)
assert_equal "Renamed", item.reload.name
- assert_equal [[item.id, "https://example.com/a"]] * 2, @source.calls
+ assert_equal [[item.id, "a"]] * 2, @source.calls
end
private
def entry(key, name: key)
- url = "https://example.com/#{key}"
- Sources::Entry.new(key: url, name:, url:)
+ Sources::Entry.new(key:, name:)
end
def sync(*keys) = Sync.call(@list, keys.map {|key| entry(key) }, source: @source)