Require user names and emails to be case insensitively unique
authorTom Hughes <tom@compton.nu>
Mon, 12 Dec 2011 19:11:06 +0000 (19:11 +0000)
committerTom Hughes <tom@compton.nu>
Mon, 12 Dec 2011 19:11:06 +0000 (19:11 +0000)
Any existing clashes are allowed to remain for now, byt any new
accounts, or changes to names on existing accounts, must be unique
without regard to case.

app/models/user.rb
db/migrate/20111212183945_add_lowercase_user_indexes.rb [new file with mode: 0644]
lib/migrate.rb

index d3a05d4..56c8890 100644 (file)
@@ -24,8 +24,8 @@ class User < ActiveRecord::Base
   validates_presence_of :email, :display_name
   validates_confirmation_of :email#, :message => ' addresses must match'
   validates_confirmation_of :pass_crypt#, :message => ' must match the confirmation password'
-  validates_uniqueness_of :display_name, :allow_nil => true
-  validates_uniqueness_of :email
+  validates_uniqueness_of :display_name, :allow_nil => true, :case_sensitive => false, :if => Proc.new { |u| u.display_name_changed? }
+  validates_uniqueness_of :email, :case_sensitive => false, :if => Proc.new { |u| u.email_changed? }
   validates_uniqueness_of :openid_url, :allow_nil => true
   validates_length_of :pass_crypt, :within => 8..255
   validates_length_of :display_name, :within => 3..255, :allow_nil => true
diff --git a/db/migrate/20111212183945_add_lowercase_user_indexes.rb b/db/migrate/20111212183945_add_lowercase_user_indexes.rb
new file mode 100644 (file)
index 0000000..27355b1
--- /dev/null
@@ -0,0 +1,13 @@
+require 'lib/migrate'
+
+class AddLowercaseUserIndexes < ActiveRecord::Migration
+  def up
+    add_index :users, :display_name, :lowercase => true, :name => "users_display_name_lower_idx"
+    add_index :users, :email, :lowercase => true, :name => "users_email_lower_idx"
+  end
+
+  def down
+    remove_index :users, :name => "users_email_lower_idx"
+    remove_index :users, :name => "users_display_name_lower_idx"
+  end
+end
index 81cdd4d..b3cffd8 100644 (file)
@@ -198,7 +198,13 @@ module ActiveRecord
         else
           index_type = options
         end
-        quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
+
+        quoted_column_names = column_names.map { |e| quote_column_name(e) }
+        if Hash === options and options[:lowercase]
+          quoted_column_names = quoted_column_names.map { |e| "LOWER(#{e})" }
+        end
+        quoted_column_names = quoted_column_names.join(", ")
+
         execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} USING #{index_method} (#{quoted_column_names})"
       end
     end