mirror of
https://github.com/discourse/discourse.git
synced 2024-12-19 09:03:45 +08:00
FIX: Avoid zipping when adding users to groups (#30263)
This commit is contained in:
parent
ebfc33b556
commit
622eb9e51c
|
@ -16,36 +16,28 @@ DiscourseAutomation::Scriptable.add(
|
||||||
triggerables %i[recurring user_first_logged_in]
|
triggerables %i[recurring user_first_logged_in]
|
||||||
|
|
||||||
script do |trigger, fields|
|
script do |trigger, fields|
|
||||||
custom_field_name = fields.dig("custom_field_name", "value")
|
|
||||||
|
|
||||||
case trigger["kind"]
|
case trigger["kind"]
|
||||||
when DiscourseAutomation::Triggers::API_CALL, DiscourseAutomation::Triggers::RECURRING
|
when DiscourseAutomation::Triggers::API_CALL, DiscourseAutomation::Triggers::RECURRING
|
||||||
query =
|
custom_field_name = "#{::User::USER_FIELD_PREFIX}#{fields.dig("custom_field_name", "value")}"
|
||||||
DB.query(<<-SQL, prefix: ::User::USER_FIELD_PREFIX, custom_field_name: custom_field_name)
|
|
||||||
SELECT u.id as user_id, g.id as group_id
|
|
||||||
FROM users u
|
|
||||||
JOIN user_custom_fields ucf
|
|
||||||
ON u.id = ucf.user_id
|
|
||||||
AND ucf.name = CONCAT(:prefix, :custom_field_name)
|
|
||||||
JOIN groups g
|
|
||||||
on g.full_name ilike ucf.value
|
|
||||||
FULL OUTER JOIN group_users gu
|
|
||||||
ON gu.user_id = u.id
|
|
||||||
AND gu.group_id = g.id
|
|
||||||
WHERE gu.id is null
|
|
||||||
AND u.active = true
|
|
||||||
ORDER BY 1, 2
|
|
||||||
SQL
|
|
||||||
|
|
||||||
groups_by_id = {}
|
# mapping of group full_names to ids for quick lookup
|
||||||
|
group_ids_by_name = Group.where.not(full_name: [nil, ""]).pluck(:full_name, :id).to_h
|
||||||
|
|
||||||
|
# find users with the custom field who aren't in their designated group
|
||||||
User
|
User
|
||||||
.where(id: query.map(&:user_id))
|
.joins(
|
||||||
.order(:id)
|
"JOIN user_custom_fields ucf ON users.id = ucf.user_id AND ucf.name = '#{custom_field_name}'",
|
||||||
.zip(query) do |user, query_row|
|
)
|
||||||
group_id = query_row.group_id
|
.where(active: true)
|
||||||
group = groups_by_id[group_id] ||= Group.find(group_id)
|
.where("ucf.value IS NOT NULL AND ucf.value != ''")
|
||||||
|
.where(
|
||||||
|
"NOT EXISTS ( SELECT 1 FROM group_users gu JOIN groups g ON g.id = gu.group_id WHERE gu.user_id = users.id AND g.full_name = ucf.value)",
|
||||||
|
)
|
||||||
|
.select("users.id, ucf.value as group_name")
|
||||||
|
.find_each do |user|
|
||||||
|
next unless group_id = group_ids_by_name[user.group_name]
|
||||||
|
|
||||||
|
group = Group.find(group_id)
|
||||||
group.add(user)
|
group.add(user)
|
||||||
GroupActionLogger.new(Discourse.system_user, group).log_add_user_to_group(user)
|
GroupActionLogger.new(Discourse.system_user, group).log_add_user_to_group(user)
|
||||||
end
|
end
|
||||||
|
@ -58,7 +50,7 @@ DiscourseAutomation::Scriptable.add(
|
||||||
WHERE ucf.user_id = :user_id AND ucf.name = CONCAT(:prefix, :custom_field_name)
|
WHERE ucf.user_id = :user_id AND ucf.name = CONCAT(:prefix, :custom_field_name)
|
||||||
SQL
|
SQL
|
||||||
prefix: ::User::USER_FIELD_PREFIX,
|
prefix: ::User::USER_FIELD_PREFIX,
|
||||||
custom_field_name: custom_field_name,
|
custom_field_name: fields.dig("custom_field_name", "value"),
|
||||||
user_id: trigger["user"].id,
|
user_id: trigger["user"].id,
|
||||||
).first
|
).first
|
||||||
next if !group_name
|
next if !group_name
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe "AddUserTogroupThroughCustomField" do
|
describe "AddUserToGroupThroughCustomField" do
|
||||||
fab!(:user_1) { Fabricate(:user) }
|
fab!(:user_1) { Fabricate(:user) }
|
||||||
fab!(:user_2) { Fabricate(:user) }
|
fab!(:user_2) { Fabricate(:user) }
|
||||||
fab!(:target_group) { Fabricate(:group, full_name: "Groupity Group") }
|
fab!(:target_group) { Fabricate(:group, full_name: "Groupity Group") }
|
||||||
|
@ -51,6 +51,22 @@ describe "AddUserTogroupThroughCustomField" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with empty field value" do
|
||||||
|
before do
|
||||||
|
UserCustomField.create!(user_id: user_1.id, name: "user_field_#{user_field.id}", value: "")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not add user to groups with empty fullnames" do
|
||||||
|
empty_fullname_group1 = Fabricate(:group, full_name: "")
|
||||||
|
empty_fullname_group2 = Fabricate(:group, full_name: "")
|
||||||
|
|
||||||
|
automation.trigger!("kind" => DiscourseAutomation::Triggers::RECURRING)
|
||||||
|
|
||||||
|
expect(user_1.reload.in_any_groups?([empty_fullname_group1.id])).to eq(false)
|
||||||
|
expect(user_1.reload.in_any_groups?([empty_fullname_group2.id])).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when group is already present" do
|
context "when group is already present" do
|
||||||
before { target_group.add(user_1) }
|
before { target_group.add(user_1) }
|
||||||
|
|
||||||
|
@ -117,4 +133,40 @@ describe "AddUserTogroupThroughCustomField" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with many users and groups" do
|
||||||
|
fab!(:bangalore) { Fabricate(:group, full_name: "Bangalore, India") }
|
||||||
|
fab!(:dublin) { Fabricate(:group, full_name: "Dublin, Ireland") }
|
||||||
|
fab!(:iowa) { Fabricate(:group, full_name: "Iowa") }
|
||||||
|
fab!(:missouri) { Fabricate(:group, full_name: "Missouri") }
|
||||||
|
|
||||||
|
fab!(:user1) { Fabricate(:user, id: bangalore.id) }
|
||||||
|
fab!(:user2) { Fabricate(:user) }
|
||||||
|
fab!(:user3) { Fabricate(:user) }
|
||||||
|
fab!(:user4) { Fabricate(:user) }
|
||||||
|
fab!(:user5) { Fabricate(:user) }
|
||||||
|
fab!(:user6) { Fabricate(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
[
|
||||||
|
[user1, "Dublin, Ireland"],
|
||||||
|
[user4, "Iowa"],
|
||||||
|
[user2, "Bangalore, India"],
|
||||||
|
[user5, ""],
|
||||||
|
[user6, "Missouri"],
|
||||||
|
[user3, "Bangalore, India"],
|
||||||
|
].each do |user, location|
|
||||||
|
UserCustomField.create!(user: user, name: "user_field_#{user_field.id}", value: location)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "adds users to their intended groups" do
|
||||||
|
automation.trigger!("kind" => DiscourseAutomation::Triggers::RECURRING)
|
||||||
|
|
||||||
|
expect(bangalore.users).to match_array([user2, user3])
|
||||||
|
expect(dublin.users).to eq([user1])
|
||||||
|
expect(iowa.users).to eq([user4])
|
||||||
|
expect(missouri.users).to eq([user6])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user