Skip to content

Commit e00f01b

Browse files
authored
Serialize user sortables with MessagePack (#1555)
1 parent d82b542 commit e00f01b

File tree

5 files changed

+62
-7
lines changed

5 files changed

+62
-7
lines changed

app/models/heat_network_order.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class HeatNetworkOrder < ApplicationRecord
1616
message: 'already exists for this scenario'
1717
}
1818

19+
1920
def self.default_order(temperature = :mt)
2021
Etsource::Config.public_send("heat_network_order_#{temperature}")
2122
end

app/models/user_sortable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module UserSortable
77
extend ActiveSupport::Concern
88

99
included do
10-
serialize :order, type: Array
10+
serialize :order, type: Array, coder: MessagePack
1111
belongs_to :scenario
1212

1313
validates_with Atlas::UserSortableValidator,

config/initializers/msgpack.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require 'msgpack'
2+
3+
module MessagePack
4+
class << self
5+
alias_method :load, :unpack
6+
alias_method :dump, :pack
7+
end
8+
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
class SerializeUserSortables < ActiveRecord::Migration[7.1]
2+
require 'msgpack'
3+
require 'yaml'
4+
5+
TARGET_MODELS = {
6+
forecast_storage_orders: 'ForecastStorageOrder',
7+
hydrogen_supply_orders: 'HydrogenSupplyOrder',
8+
hydrogen_demand_orders: 'HydrogenDemandOrder',
9+
households_space_heating_producer_orders: 'HouseholdsSpaceHeatingProducerOrder',
10+
heat_network_orders: 'HeatNetworkOrder'
11+
}.freeze
12+
13+
def up
14+
TARGET_MODELS.each do |table_name, model_name|
15+
say "Serializing #{model_name}#order → MessagePack binary"
16+
17+
rename_column table_name, :order, :order_old
18+
add_column table_name, :order, :binary, limit: 64.kilobytes
19+
20+
record_class = Class.new(ActiveRecord::Base) do
21+
self.table_name = table_name.to_s
22+
end
23+
record_class.reset_column_information
24+
25+
record_class.find_each do |record|
26+
json = record.read_attribute_before_type_cast('order_old')
27+
next if json.blank? || !json.is_a?(String)
28+
29+
array = YAML.safe_load(
30+
json,
31+
permitted_classes: [Array, String, Symbol],
32+
aliases: true
33+
)
34+
next unless array.is_a?(Array)
35+
36+
msgpack_blob = array.to_msgpack
37+
record_class.where(id: record.id).update_all(order: msgpack_blob)
38+
end
39+
end
40+
end
41+
end

db/schema.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.1].define(version: 2025_04_15_093227) do
13+
ActiveRecord::Schema[7.1].define(version: 2025_04_17_090853) do
1414
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
1515
t.string "name", limit: 191, null: false
1616
t.string "record_type", limit: 191, null: false
@@ -41,33 +41,38 @@
4141

4242
create_table "forecast_storage_orders", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
4343
t.integer "scenario_id"
44-
t.text "order"
44+
t.text "order_old"
45+
t.binary "order", size: :medium
4546
t.index ["scenario_id"], name: "index_forecast_storage_orders_on_scenario_id", unique: true
4647
end
4748

4849
create_table "heat_network_orders", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
4950
t.integer "scenario_id"
50-
t.text "order"
51+
t.text "order_old"
5152
t.string "temperature", default: "mt"
53+
t.binary "order", size: :medium
5254
t.index ["scenario_id", "temperature"], name: "index_heat_network_orders_on_scenario_id_and_temperature", unique: true
5355
t.index ["scenario_id"], name: "index_heat_network_orders_on_scenario_id"
5456
end
5557

5658
create_table "households_space_heating_producer_orders", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
5759
t.integer "scenario_id"
58-
t.text "order"
60+
t.text "order_old"
61+
t.binary "order", size: :medium
5962
t.index ["scenario_id"], name: "index_households_space_heating_producer_orders_on_scenario_id", unique: true
6063
end
6164

6265
create_table "hydrogen_demand_orders", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
6366
t.integer "scenario_id"
64-
t.text "order"
67+
t.text "order_old"
68+
t.binary "order", size: :medium
6569
t.index ["scenario_id"], name: "index_hydrogen_demand_orders_on_scenario_id", unique: true
6670
end
6771

6872
create_table "hydrogen_supply_orders", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
6973
t.integer "scenario_id"
70-
t.text "order"
74+
t.text "order_old"
75+
t.binary "order", size: :medium
7176
t.index ["scenario_id"], name: "index_hydrogen_supply_orders_on_scenario_id", unique: true
7277
end
7378

0 commit comments

Comments
 (0)