Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit a3466c7

Browse files
committed
FIX: system persona state leaking between sites
System personas leaned on reused classes, this was a problem in a multisite environement cause state, such as "enabled" ended up being reused between sites. New implementation ensures state is pristine between sites in a multisite
1 parent 8b1b681 commit a3466c7

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

app/models/ai_persona.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,19 @@ def class_instance
226226

227227
persona_class = DiscourseAi::Personas::Persona.system_personas_by_id[self.id]
228228
if persona_class
229-
instance_attributes.each do |key, value|
230-
# description/name are localized
231-
persona_class.define_singleton_method(key) { value } if key != :description && key != :name
232-
end
233-
persona_class.define_method(:options) { options }
234-
return persona_class
229+
return(
230+
# we need a new copy so we don't leak information
231+
# across sites
232+
Class.new(persona_class) do
233+
# required for localization
234+
define_singleton_method(:to_s) { persona_class.to_s }
235+
instance_attributes.each do |key, value|
236+
# description/name are localized
237+
define_singleton_method(key) { value } if key != :description && key != :name
238+
end
239+
define_method(:options) { options }
240+
end
241+
)
235242
end
236243

237244
ai_persona_id = self.id
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe AiPersona, type: :multisite do
4+
it "is able to amend settings on system personas on multisite" do
5+
persona = AiPersona.find_by(name: "Designer")
6+
expect(persona.allow_personal_messages).to eq(true)
7+
persona.update!(allow_personal_messages: false)
8+
9+
instance = persona.class_instance
10+
expect(instance.allow_personal_messages).to eq(false)
11+
12+
test_multisite_connection("second") do
13+
persona = AiPersona.find_by(name: "Designer")
14+
expect(persona.allow_personal_messages).to eq(true)
15+
instance = persona.class_instance
16+
expect(instance.name).to eq("Designer")
17+
expect(instance.allow_personal_messages).to eq(true)
18+
end
19+
20+
persona = AiPersona.find_by(name: "Designer")
21+
instance = persona.class_instance
22+
expect(instance.allow_personal_messages).to eq(false)
23+
end
24+
end

0 commit comments

Comments
 (0)