diff --git a/app/models/user.rb b/app/models/user.rb
index 96dcaaa76..1d9b553cf 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -131,7 +131,7 @@ class User < ApplicationRecord
validates :following_orgs_count, presence: true
validates :following_tags_count, presence: true
validates :following_users_count, presence: true
- validates :name, length: { in: 1..100 }
+ validates :name, length: { in: 1..100 }, presence: true
validates :password, length: { in: 8..100 }, allow_nil: true
validates :payment_pointer, format: PAYMENT_POINTER_REGEXP, allow_blank: true
validates :rating_votes_count, presence: true
diff --git a/app/views/users/_errors.html.erb b/app/views/users/_errors.html.erb
index 85a4553e1..3704e0b53 100644
--- a/app/views/users/_errors.html.erb
+++ b/app/views/users/_errors.html.erb
@@ -1,7 +1,7 @@
diff --git a/lib/data_update_scripts/20230718102644_backfill_user_blank_name.rb b/lib/data_update_scripts/20230718102644_backfill_user_blank_name.rb
new file mode 100644
index 000000000..3ed675bc5
--- /dev/null
+++ b/lib/data_update_scripts/20230718102644_backfill_user_blank_name.rb
@@ -0,0 +1,9 @@
+module DataUpdateScripts
+ class BackfillUserBlankName
+ def run
+ User.where(" TRIM(name)='' ").each do |user|
+ user.update_column(:name, user.username)
+ end
+ end
+ end
+end
diff --git a/spec/lib/data_update_scripts/backfill_user_blank_name_spec.rb b/spec/lib/data_update_scripts/backfill_user_blank_name_spec.rb
new file mode 100644
index 000000000..ae6a5e751
--- /dev/null
+++ b/spec/lib/data_update_scripts/backfill_user_blank_name_spec.rb
@@ -0,0 +1,33 @@
+require "rails_helper"
+require Rails.root.join(
+ "lib/data_update_scripts/20230718102644_backfill_user_blank_name.rb",
+)
+
+describe DataUpdateScripts::BackfillUserBlankName do
+ let(:invalid_user_with_blank_name) { make_user_for(" ", "user_name") }
+ let(:valid_user_name_with_trailing_spaces) { create(:user, name: " Name ") }
+ let(:valid_user) { create(:user) }
+
+ def make_user_for(name, username)
+ build(:user, name: name, username: username).tap do |user|
+ user.save(validate: false)
+ end
+ end
+
+ it "replaces the blank name with the username" do
+ username = invalid_user_with_blank_name.username
+
+ expect { described_class.new.run }
+ .to change { invalid_user_with_blank_name.reload.name }
+ .from(" ")
+ .to(username)
+ end
+
+ it "does not modify the name if it has trailing whitespaces" do
+ expect { described_class.new.run }.not_to change(:valid_user_name_with_trailing_spaces, :name)
+ end
+
+ it "does not modify the name if it is valid" do
+ expect { described_class.new.run }.not_to change(:valid_user, :name)
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 8154a900c..f5b584c9c 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -193,6 +193,8 @@ RSpec.describe User do
it { is_expected.to validate_length_of(:password).is_at_most(100).is_at_least(8) }
it { is_expected.to validate_length_of(:username).is_at_most(30).is_at_least(2) }
+ it { is_expected.not_to allow_value(" ").for(:name) }
+
it { is_expected.to validate_presence_of(:articles_count) }
it { is_expected.to validate_presence_of(:badge_achievements_count) }
it { is_expected.to validate_presence_of(:blocked_by_count) }