User.select(:name).group(:name).having("count(*) > 1")
此查询可以正常选择具有重复用户名的记录。但面临的问题是名称中有空间。
例如。
recoed1 = "Username"
record2 = "Username "
这是两条记录,但它们具有相同的名称,但上面的查询将它们视为不同的记录,因为第二条记录中有空格。所以在选择时我没有得到这个记录。
任何使用普通mysql查询或rails的解决方案都可以。
OR
如何使用rails / mysql查询首先从表中剥离或修剪所有列数据。然后我可以申请以上查询。
答案 0 :(得分:1)
您可以使用mysql's string functions:
User.select("lower(trim(name))").group("lower(trim(name))").having("count(*) > 1")
答案 1 :(得分:0)
我在这里要做的是确保您的数据首先是整洁的。
您可以使用预验证方法在用户名上调用strip
。你可以这样做
#in lib/trimmer.rb
module Trimmer
# Make a class method available to define space-trimming behavior.
def self.included base
base.extend(ClassMethods)
end
module ClassMethods
# Register a before-validation handler for the given fields to
# trim leading and trailing spaces.
def trimmed_fields *field_list
before_validation do |model|
field_list.each do |field|
model.send("#{field}=", model.send("#{field}").strip) if model.send("#{field}").respond_to?('strip')
end
end
end
end
end
确保此模块是必需的,无论您在配置中需要lib中的内容。
现在,你可以说,在任何模型中都是这样的(在这个例子中,我正在做除了用户名之外的其他一些领域)
class User < ActiveRecord::Base
include Trimmer
trimmed_fields :username, :email, :first_name, :last_name
...
所以,这将解决你前进的问题。剩下的步骤是整理现有数据。我会在迁移中这样做。 (再次,我正在做一些其他领域作为例子)
tables_and_cols = {"users" => %w(username email first_name last_name), "foos" => %w(bar baz)}
tables_and_cols.each do |table, cols|
cols.each do |col|
ActiveRecord::Base.connection.execute("update #{tablename} set #{col} = trim(#{col})")
end
end
现在,执行此修剪后,您可能会有一些重复的用户名。您将需要决定如何处理该问题,因为所涉及的记录不再有效。如果您还没有公开部署它,即如果您没有任何活跃的真实用户,那么无关紧要:您可以将用户名更改为其他用户名。但是,如果您确实有真正的人使用它,您可能需要更改其中一些用户名并通知他们。如果您想维持人们在用户名的开头或结尾不能有空格的情况,这是不可避免的。