Models for column positioning
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
class Column < ApplicationRecord
|
||||
include Positioned
|
||||
|
||||
belongs_to :collection, touch: true
|
||||
has_many :cards, dependent: :nullify
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
module Column::Positioned
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :sorted, -> { order(position: :asc) }
|
||||
|
||||
before_create :set_position
|
||||
end
|
||||
|
||||
def move_left
|
||||
if column = collection.columns.where("position < ?", position).sorted.last
|
||||
swap_position_with(column)
|
||||
end
|
||||
end
|
||||
|
||||
def move_right
|
||||
if column = collection.columns.where("position > ?", position).sorted.first
|
||||
swap_position_with(column)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def set_position
|
||||
max_position = collection.columns.maximum(:position)
|
||||
self.position = max_position + 1
|
||||
end
|
||||
|
||||
def swap_position_with(other_column)
|
||||
transaction do
|
||||
other_column.position, self.position = self.position, other_column.position
|
||||
other_column.save!
|
||||
save!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,7 +16,7 @@
|
||||
<%= render "collections/show/stream", collection: collection, page: page %>
|
||||
|
||||
<div class="card-columns__right">
|
||||
<%= render partial: "collections/show/column", collection: collection.columns, cached: true %>
|
||||
<%= render partial: "collections/show/column", collection: collection.columns.sorted, cached: true %>
|
||||
<%= render "collections/show/closed", collection: collection %>
|
||||
|
||||
<%= render "collections/show/menu/columns", collection: collection %>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class AddPositionToColumns < ActiveRecord::Migration[8.2]
|
||||
def change
|
||||
add_column :columns, :position, :integer, default: 0
|
||||
|
||||
execute "UPDATE columns SET position = 0"
|
||||
|
||||
change_column_null :columns, :position, false
|
||||
end
|
||||
end
|
||||
Generated
+2
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_10_29_104115) do
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_10_29_142418) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.datetime "accessed_at"
|
||||
t.integer "collection_id", null: false
|
||||
@@ -191,6 +191,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_10_29_104115) do
|
||||
t.string "color", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.integer "position", default: 0, null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["collection_id"], name: "index_columns_on_collection_id"
|
||||
end
|
||||
|
||||
+11
-1
@@ -562,6 +562,16 @@ columns:
|
||||
- *5
|
||||
- *6
|
||||
- *10
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: position
|
||||
cast_type: *3
|
||||
sql_type_metadata: *4
|
||||
'null': false
|
||||
default: 0
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *9
|
||||
comments:
|
||||
- *22
|
||||
@@ -2818,4 +2828,4 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
version: 20251029104115
|
||||
version: 20251029142418
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
require "test_helper"
|
||||
|
||||
class Column::PositionedTest < ActiveSupport::TestCase
|
||||
test "auto position new columns" do
|
||||
collection = collections(:writebook)
|
||||
max_position = collection.columns.maximum(:position)
|
||||
|
||||
new_column = collection.columns.create!(name: "New Column", color: "#000000")
|
||||
|
||||
assert_equal max_position + 1, new_column.position
|
||||
end
|
||||
|
||||
test "move column to the left" do
|
||||
collection = collections(:writebook)
|
||||
columns = collection.columns.sorted.to_a
|
||||
|
||||
column_a = columns[0]
|
||||
column_b = columns[1]
|
||||
original_position_a = column_a.position
|
||||
original_position_b = column_b.position
|
||||
|
||||
column_b.move_left
|
||||
|
||||
assert_equal original_position_b, column_a.reload.position
|
||||
assert_equal original_position_a, column_b.reload.position
|
||||
end
|
||||
|
||||
test "move left when already at leftmost position" do
|
||||
collection = collections(:writebook)
|
||||
leftmost_column = collection.columns.sorted.first
|
||||
original_position = leftmost_column.position
|
||||
|
||||
leftmost_column.move_left
|
||||
|
||||
assert_equal original_position, leftmost_column.reload.position
|
||||
end
|
||||
|
||||
test "move column to the right" do
|
||||
collection = collections(:writebook)
|
||||
columns = collection.columns.sorted.to_a
|
||||
|
||||
column_a = columns[0]
|
||||
column_b = columns[1]
|
||||
original_position_a = column_a.position
|
||||
original_position_b = column_b.position
|
||||
|
||||
column_a.move_right
|
||||
|
||||
assert_equal original_position_b, column_a.reload.position
|
||||
assert_equal original_position_a, column_b.reload.position
|
||||
end
|
||||
|
||||
test "move right when already at rightmost position" do
|
||||
collection = collections(:writebook)
|
||||
rightmost_column = collection.columns.sorted.last
|
||||
original_position = rightmost_column.position
|
||||
|
||||
rightmost_column.move_right
|
||||
|
||||
assert_equal original_position, rightmost_column.reload.position
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user