diff --git a/app/models/user.rb b/app/models/user.rb index f44295d3..199ccd54 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -28,7 +28,7 @@ class User < ActiveRecord::Base validates :username, :email, presence: true validates :username, uniqueness: true, if: :username? validates :username, length: { in: 3..30 }, allow_nil: true - validates :email, format: { with: /@/ }, uniqueness: true, if: :email?, on: :create + validates :email, format: { with: /@/ }, uniqueness: true validates :url, format: URI::regexp(%w(http https)), allow_nil: true, allow_blank: true, on: :create has_many :devices, foreign_key: 'owner_id', after_add: :update_cached_device_ids!, after_remove: :update_cached_device_ids! diff --git a/lib/tasks/pgsequences.rake b/lib/tasks/pgsequences.rake deleted file mode 100644 index adf01c30..00000000 --- a/lib/tasks/pgsequences.rake +++ /dev/null @@ -1,9 +0,0 @@ -namespace :pgsequences do - desc "Reset all Postgres sequences" - task :reset => :environment do - ActiveRecord::Base.connection.tables.each do |t| - ActiveRecord::Base.connection.reset_pk_sequence!(t) - puts "Reset pk sequence on table: #{t}" - end - end -end diff --git a/lib/tasks/users.rake b/lib/tasks/users.rake new file mode 100644 index 00000000..d1e8ae8f --- /dev/null +++ b/lib/tasks/users.rake @@ -0,0 +1,55 @@ +namespace :users do + task :remove_null_emails => :environment do + team_user = User.find_by_email("team@pral2a.com") + count_team_devices = team_user.devices.length + count_users = User.count + count_moved_devices = 0 + count_deleted_users = 0 + User.where("email IS NULL or trim(email) = ''").each do |user| + puts "user #{user.id} (#{user.username}) has blank email, moving devices to team account:" + user.devices.each do |device| + device.owner = team_user + device.save(validate: false) + count_team_devices += 1 + count_moved_devices += 1 + puts "\t - Device #{device.id} moved to user: #{team_user.id}" + end + user.destroy! + count_users -= 1 + count_deleted_users += 1 + end + puts "Check moved devices: #{team_user.reload.devices.length} (should be #{count_team_devices}, #{count_moved_devices} moved)" + puts "Check remaining users: #{User.count} (should be #{count_users}, #{count_deleted_users} deleted)" + end + + task :deduplicate_emails => :environment do + count_deleted_users = 0 + count_users = User.count + count_devices = Device.count + count_moved_devices = 0 + ActiveRecord::Base.connection.execute( + "SELECT email FROM users GROUP BY email HAVING count(id) > 1" + ).each do |record| + email = record["email"] + users = User.where(email: email).to_a + puts "Found #{users.length} users for email: #{email}: (#{users.map(&:id).join(",")})" + move_to_user = users.shift + puts " - Moving devices from users (#{users.map(&:id).join(",")}) to user #{move_to_user.id}" + users.each do |user| + user.devices.each do |device| + device.owner = move_to_user + device.save(validate: false) + count_moved_devices += 1 + puts " - Moved device #{device.id} to user: #{move_to_user.id}" + end + end + puts " - Deleting users: #{users.map(&:id).join(",")}" + users.each do |user| + user.destroy! + count_deleted_users += 1 + end + end + puts "Check moved devices: #{Device.count} (should be #{count_devices}, #{count_moved_devices} moved)" + puts "Check deleted users: #{User.count} (should be #{count_users - count_deleted_users}, #{count_deleted_users} deleted)" + end +end \ No newline at end of file diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 07fa099d..fafe6ae7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -34,6 +34,19 @@ expect(build(:user, avatar: 'http://i.imgur.com/SZD8ADL.JPEG')).to be_valid end + it "is invalid with an email which isn't an email adddress" do + expect(build(:user, email: "not an email")).to be_invalid + end + + it "is invalid without an email" do + expect(build(:user, email: nil)).to be_invalid + end + + it "is invalid with an email which is already taken" do + create(:user, email: "taken@example.com") + expect(build(:user, email: "taken@example.com")).to be_invalid + end + it "has a location" do user = create(:user, country_code: 'es', city: 'Barcelona') expect(user.country.to_s).to eq("Spain")