Skip to content

Instantly share code, notes, and snippets.

@plainprogrammer
Last active October 28, 2015 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plainprogrammer/d58fb85296f44361b973 to your computer and use it in GitHub Desktop.
Save plainprogrammer/d58fb85296f44361b973 to your computer and use it in GitHub Desktop.
Scary Reorder Service
module Services
module Column
class Reorder
attr_reader :column_to_move, :column_before, :column_set
def initialize(column_to_move_id, column_before_id = nil)
@column_to_move = ::Column.find(column_to_move_id)
@column_before = ::Column.find(column_before_id) if column_before_id.present?
@column_set = @column_to_move.column_set
end
def reorder
if column_before
if column_before.position > column_to_move.position
columns_to_reorder = column_set.columns.where('position <= ?', column_before.position)
.where('position > ?', column_to_move.position)
.where('id != ?', column_to_move)
.pluck(:id)
ActiveRecord::Base.transaction do
column_to_move.update_attributes!(position: column_before.position)
::Column.where(id: columns_to_reorder).each do |column|
column.update_attributes!(position: column.position - 1)
end
end
else
columns_to_reorder = column_set.columns.where('position > ?', column_before.try(:position) || 0)
.where('position < ?', column_to_move.position)
.where('id != ?', column_to_move)
.pluck(:id)
ActiveRecord::Base.transaction do
column_to_move.update_attributes!(position: column_before.position + 1)
::Column.where(id: columns_to_reorder).each do |column|
column.update_attributes!(position: column.position + 1)
end
end
end
else
columns_to_reorder = column_set.columns.where('position >= ?', column_before.try(:position) || 0)
.where('position < ?', column_to_move.position)
.where('id != ?', column_to_move)
.pluck(:id)
ActiveRecord::Base.transaction do
column_to_move.update_attributes!(position: 0)
::Column.where(id: columns_to_reorder).each do |column|
column.update_attributes!(position: column.position + 1)
end
end
end
end
end
end
end
require 'spec_helper'
describe Services::Column::Reorder do
let(:user) { users(:jane) }
let(:column_set) { create_column_set(user: user) }
let!(:column0) { create_column(column_set: column_set, position: 0) }
let!(:column1) { create_column(column_set: column_set, position: 1) }
let!(:column2) { create_column(column_set: column_set, position: 2) }
let!(:column3) { create_column(column_set: column_set, position: 3) }
describe "moving a column to the top of the set" do
let(:subject) { Services::Column::Reorder.new(column2.id, "") }
it "does not move column3" do
expect { subject.reorder }.to_not change { column3.reload.position }
end
it "moves column2 to position 0" do
expect { subject.reorder }.to change { column2.reload.position }.from(2).to(0)
end
it "moves column0 down 1 position" do
expect { subject.reorder }.to change { column0.reload.position }.from(0).to(1)
end
it "moves column1 down 1 position" do
expect { subject.reorder }.to change { column1.reload.position }.from(1).to(2)
end
end
describe "moving a column up within the set" do
let(:subject) { Services::Column::Reorder.new(column2.id, column0.id) }
it "does not move column3" do
expect { subject.reorder }.to_not change { column3.reload.position }
end
it "moves column2 to position 1" do
expect { subject.reorder }.to change { column2.reload.position }.from(2).to(1)
end
it "does not move column0" do
expect { subject.reorder }.to_not change { column0.reload.position }
end
it "moves column1 down 1 position" do
expect { subject.reorder }.to change { column1.reload.position }.from(1).to(2)
end
end
describe "moving a column down within the set" do
let(:subject) { Services::Column::Reorder.new(column1.id, column2.id) }
it "does not move column3" do
expect { subject.reorder }.to_not change { column3.reload.position }
end
it "moves column2 to position 1" do
expect { subject.reorder }.to change { column2.reload.position }.from(2).to(1)
end
it "does not move column0" do
expect { subject.reorder }.to_not change { column0.reload.position }
end
it "moves column1 to position 2" do
expect { subject.reorder }.to change { column1.reload.position }.from(1).to(2)
end
end
describe "moving a column to the bottom of the set" do
let(:subject) { Services::Column::Reorder.new(column1.id, column3.id) }
it "moves column3 to position 2" do
expect { subject.reorder }.to change { column3.reload.position }.from(3).to(2)
end
it "moves column2 to position 1" do
expect { subject.reorder }.to change { column2.reload.position }.from(2).to(1)
end
it "does not move column0" do
expect { subject.reorder }.to_not change { column0.reload.position }
end
it "moves column1 to position 3" do
expect { subject.reorder }.to change { column1.reload.position }.from(1).to(3)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment