--- /dev/null
+class BackfillMissingSlugs < ActiveRecord::Migration[7.2]
+ def up
+ # First, let's identify posts without slugs
+ posts_without_slugs = Post.where(slug: [nil, ''])
+
+ puts "Found #{posts_without_slugs.count} posts without slugs"
+
+ posts_without_slugs.each do |post|
+ # Generate a base slug from title or URL
+ base_slug = if post.title.present?
+ post.title.parameterize
+ elsif post.bookmark? && post.url.present?
+ begin
+ uri = URI.parse(post.url)
+ domain_slug = uri.host.gsub(/^www\./, '').parameterize
+ timestamp = post.created_at.strftime('%Y%m%d%H%M%S')
+ "#{domain_slug}-#{timestamp}"
+ rescue URI::InvalidURIError
+ "bookmark-#{SecureRandom.uuid}"
+ end
+ else
+ "post-#{SecureRandom.uuid}"
+ end
+
+ # Ensure uniqueness
+ slug = base_slug
+ counter = 1
+
+ while Post.where.not(id: post.id).exists?(slug: slug)
+ slug = "#{base_slug}-#{counter}"
+ counter += 1
+ end
+
+ # Update the post with the new slug
+ post.update_column(:slug, slug)
+ puts "Updated post #{post.id} with slug: #{slug}"
+ end
+
+ # After backfilling, add a NOT NULL constraint if it doesn't exist
+ unless column_exists?(:posts, :slug, null: false)
+ change_column_null :posts, :slug, false
+ end
+ end
+
+ def down
+ # If we need to rollback, we'll remove the NOT NULL constraint
+ change_column_null :posts, :slug, true
+ end
+end
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.2].define(version: 2025_01_09_031618) do
+ActiveRecord::Schema[7.2].define(version: 2025_01_09_034726) do
create_table "api_keys", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "key"
t.datetime "created_at", null: false
create_table "posts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "post_type"
t.string "title"
- t.string "slug"
+ t.string "slug", null: false
t.datetime "published_at"
t.text "excerpt"
t.text "tags"