Add basic column models and script to migrate
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git merge:*)",
|
||||
"Bash(git add:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class Cards::DropsController < ApplicationController
|
||||
end
|
||||
|
||||
def render_column_replacement
|
||||
columns = Cards::Columns.new(user_filtering: @user_filtering, page_size: CardsController::PAGE_SIZE)
|
||||
columns = Cards::OldColumns.new(user_filtering: @user_filtering, page_size: CardsController::PAGE_SIZE)
|
||||
column = columns.public_send(@drop_target)
|
||||
|
||||
if @drop_target == :doing && params[:stage_id].present?
|
||||
|
||||
@@ -11,7 +11,7 @@ class CardsController < ApplicationController
|
||||
PAGE_SIZE = 25
|
||||
|
||||
def index
|
||||
@columns = Cards::Columns.new(user_filtering: @user_filtering, page_size: PAGE_SIZE)
|
||||
@columns = Cards::OldColumns.new(user_filtering: @user_filtering, page_size: PAGE_SIZE)
|
||||
|
||||
fresh_when etag: @columns
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ class Card < ApplicationRecord
|
||||
|
||||
belongs_to :collection, touch: true
|
||||
belongs_to :creator, class_name: "User", default: -> { Current.user }
|
||||
belongs_to :column, optional: true
|
||||
|
||||
has_many :comments, dependent: :destroy
|
||||
has_one_attached :image, dependent: :purge_later
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class Cards::Columns::Column
|
||||
class Cards::OldColumns::Column
|
||||
attr_reader :page, :filter, :user_filtering
|
||||
|
||||
def initialize(page:, filter:, user_filtering:)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class Cards::Columns
|
||||
class Cards::OldColumns
|
||||
attr_reader :user_filtering, :page_size
|
||||
|
||||
delegate :filter, to: :user_filtering
|
||||
@@ -5,6 +5,7 @@ class Collection < ApplicationRecord
|
||||
|
||||
has_rich_text :public_description
|
||||
|
||||
has_many :columns, dependent: :destroy
|
||||
has_many :cards, dependent: :destroy
|
||||
has_many :tags, -> { distinct }, through: :cards
|
||||
has_many :events
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Column < ApplicationRecord
|
||||
belongs_to :collection
|
||||
has_many :cards, dependent: :nullify
|
||||
|
||||
validates :name, presence: true
|
||||
validates :color, presence: true
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
class CreateColumnsAndAddColumnIdToCards < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :columns do |t|
|
||||
t.string :name, null: false
|
||||
t.string :color, null: false
|
||||
t.references :collection, null: false, foreign_key: true
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_reference :cards, :column, foreign_key: true, index: true
|
||||
end
|
||||
end
|
||||
Generated
+14
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_09_17_064006) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_09_24_100149) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.datetime "accessed_at"
|
||||
t.integer "collection_id", null: false
|
||||
@@ -133,6 +133,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_09_17_064006) do
|
||||
|
||||
create_table "cards", force: :cascade do |t|
|
||||
t.integer "collection_id", null: false
|
||||
t.integer "column_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.date "due_on"
|
||||
@@ -142,6 +143,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_09_17_064006) do
|
||||
t.string "title"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["collection_id"], name: "index_cards_on_collection_id"
|
||||
t.index ["column_id"], name: "index_cards_on_column_id"
|
||||
t.index ["last_active_at", "status"], name: "index_cards_on_last_active_at_and_status"
|
||||
t.index ["stage_id"], name: "index_cards_on_stage_id"
|
||||
end
|
||||
@@ -197,6 +199,15 @@ ActiveRecord::Schema[8.1].define(version: 2025_09_17_064006) do
|
||||
t.index ["filter_id"], name: "index_collections_filters_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "columns", force: :cascade do |t|
|
||||
t.integer "collection_id", null: false
|
||||
t.string "color", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["collection_id"], name: "index_columns_on_collection_id"
|
||||
end
|
||||
|
||||
create_table "comments", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -508,11 +519,13 @@ ActiveRecord::Schema[8.1].define(version: 2025_09_17_064006) do
|
||||
add_foreign_key "ai_quotas", "users"
|
||||
add_foreign_key "card_activity_spikes", "cards"
|
||||
add_foreign_key "card_goldnesses", "cards"
|
||||
add_foreign_key "cards", "columns"
|
||||
add_foreign_key "cards", "workflow_stages", column: "stage_id"
|
||||
add_foreign_key "closures", "cards"
|
||||
add_foreign_key "closures", "users"
|
||||
add_foreign_key "collection_publications", "collections"
|
||||
add_foreign_key "collections", "workflows"
|
||||
add_foreign_key "columns", "collections"
|
||||
add_foreign_key "comments", "cards"
|
||||
add_foreign_key "conversation_messages", "conversations"
|
||||
add_foreign_key "conversations", "users"
|
||||
|
||||
+62
-1
@@ -435,6 +435,16 @@ columns:
|
||||
- *9
|
||||
cards:
|
||||
- *24
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: column_id
|
||||
cast_type: *3
|
||||
sql_type_metadata: *4
|
||||
'null': true
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *5
|
||||
- &25 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
@@ -610,6 +620,22 @@ columns:
|
||||
collections_filters:
|
||||
- *24
|
||||
- *20
|
||||
columns:
|
||||
- *24
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: color
|
||||
cast_type: *7
|
||||
sql_type_metadata: *8
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *5
|
||||
- *6
|
||||
- *10
|
||||
- *9
|
||||
comments:
|
||||
- *23
|
||||
- *5
|
||||
@@ -1495,6 +1521,7 @@ primary_keys:
|
||||
collection_publications: id
|
||||
collections: id
|
||||
collections_filters:
|
||||
columns: id
|
||||
comments: id
|
||||
conversation_messages: id
|
||||
conversations: id
|
||||
@@ -1549,6 +1576,7 @@ data_sources:
|
||||
collection_publications: true
|
||||
collections: true
|
||||
collections_filters: true
|
||||
columns: true
|
||||
comments: true
|
||||
conversation_messages: true
|
||||
conversations: true
|
||||
@@ -1989,6 +2017,22 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: cards
|
||||
name: index_cards_on_column_id
|
||||
unique: false
|
||||
columns:
|
||||
- column_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: cards
|
||||
name: index_cards_on_last_active_at_and_status
|
||||
@@ -2205,6 +2249,23 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
columns:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: columns
|
||||
name: index_columns_on_collection_id
|
||||
unique: false
|
||||
columns:
|
||||
- collection_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
comments:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: comments
|
||||
@@ -3191,4 +3252,4 @@ indexes:
|
||||
comment:
|
||||
valid: true
|
||||
workflows: []
|
||||
version: 20250917064006
|
||||
version: 20250924100149
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative "../../config/environment"
|
||||
|
||||
ApplicationRecord.with_each_tenant do |tenant|
|
||||
puts "Processing tenant: #{tenant}"
|
||||
|
||||
Collection.find_each do |collection|
|
||||
next unless collection.workflow.present?
|
||||
|
||||
# Map to track stage_id -> column
|
||||
columns_by_stage = {}
|
||||
|
||||
# Create columns from workflow stages
|
||||
collection.workflow.stages.find_each do |stage|
|
||||
column = collection.columns.create!(
|
||||
name: stage.name,
|
||||
color: stage.color || Card::Colored::COLORS.first
|
||||
)
|
||||
columns_by_stage[stage] = column
|
||||
puts "Created column '#{column.name}' for collection '#{collection.name}'"
|
||||
end
|
||||
|
||||
# Associate cards with their corresponding columns based on stages
|
||||
collection.cards.includes(:stage).find_each do |card|
|
||||
next unless card.stage.present?
|
||||
|
||||
unless card.stage.workflow.collections.include?(collection)
|
||||
puts "Corrupt data: the card with id #{card.id} has the stage #{card.stage.name} with id #{card.stage.id} that belongs to a workflow not asociated ot its collection"
|
||||
next
|
||||
end
|
||||
|
||||
stage = columns_by_stage[card.stage]
|
||||
card.update!(column: stage)
|
||||
puts "Associated card ##{card.id} with column '#{stage.name}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
puts "Migration completed!"
|
||||
Reference in New Issue
Block a user