【问题标题】:Set nickname to name in downcase in RAILS migration在 RAILS 迁移中将昵称设置为小写的名称
【发布时间】:2016-11-04 05:37:33
【问题描述】:

我正在使用其中名称列存在的用户模型,但现在我想添加一个昵称列,默认昵称是小写的用户名称。如何做到这一点?

【问题讨论】:

  • 您想在迁移文件本身中实现这一切吗?或者它可以在模型中?
  • @Sravan 我希望它在迁移本身中完成
  • 您想添加一个新列并将所有用户名的值更新为小写的昵称吗?
  • @Sravan 是的,正确
  • @Sravan,我有一个问题,假设在 name 列中输入的名称是全名,我只想要像“John Doe”这样的名字我只希望名字 John 是小写的昵称

标签: mysql ruby-on-rails ruby rails-migrations


【解决方案1】:

这样做,

class AddNicknameToUser < ActiveRecord::Migration
  def change
    add_column :users, :nickname, :string
    User.update_all("nickname = lower(name)")
  end
end

我假设您使用的是 postgres。Update all 会比保存每条记录更快。

对于mysql:

class AddNicknameToUser < ActiveRecord::Migration
  def change
    add_column :users, :nickname, :string
    User.update_all("nickname = LOWER(name)")
  end
end

编辑:两个版本(lower 和 LOWER)都适用于 postgres 和 mysql。

【讨论】:

  • 其实我用的是MySQL
  • 第二个版本应该可以在 MySQL 和 Postgres 中运行。
  • 或者更好的是,在您的迁移中根本不要使用User 模型(或任何其他模型),而是使用简单的execute 'update users set nickname = lower(name)'。这有助于使您的迁移独立于 Ruby 代码的当前状态,并有助于避免不愉快的问题。此外,LOWERlower 在 SQL 中是相同的,因为 SQL 不区分大小写。
【解决方案2】:

由于迁移文件是ruby files,您也可以在迁移文件中使用rails models

class AddNicknameToUser < ActiveRecord::Migration
  def up
    add_column :users, :nickname, :string
    User.find_each do |user|
      user.nickname = user.try(:name).downcase
      user.save!
    end
  end

  def down
    remove_column :users, :nickname
  end
end

你也可以使用,

User.find_each do |user|
      user.update_attributes(:nickname => user.try(:name).downcase)
end

编辑:

由于您只需要拆分名称的第一个单词,因此可以使用,

user.try(:name).split.first.downcase

【讨论】:

  • 强烈建议人们不要使用模型代码进行数据库迁移。通常情况下,这些迁移中引用的模型会随着时间的推移而发生巨大的变化,有时甚至会被删除,这使得这段代码无法正常工作,除非有人想办法更新它。您可以使用(更快!)execute "UPDATE users SET nickname=LOWER(nickname) 来解决此问题,并在 SQL 中完成所有操作。
猜你喜欢
  • 1970-01-01
  • 2018-04-18
  • 2013-07-09
  • 2019-06-17
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2017-08-17
  • 2019-07-26
相关资源
最近更新 更多