【问题标题】:Add value to postgres column if that model has no value for column如果该模型没有列值,则向 postgres 列添加值
【发布时间】:2014-09-22 19:37:55
【问题描述】:

我需要检查所有当前的用户模型并检查属性 new_attribute 是否有值,如果有,那么我想保留它,如果没有,那么我想给它一个值。

举个例子。如果 User 模型在它的 school 列中有值,那么它会保留,但如果它没有值,那么它将被赋予值“None”。

这是我在迁移中应该做的事情吗?我将如何编写该迁移?

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    您应该编写迁移。有两种写迁移的方法。

    执行直接查询

    def up
      execute("update users set school='None' where school is null")
    end
    
    def down
      raise ActiveRecord::IrreversibleMigration
    end
    

    使用 ActiveRecord

    def up
      User.where("school is null").update_all(school: 'None')
    end
    
    def down
      raise ActiveRecord::IrreversibleMigration
    end
    

    【讨论】:

      【解决方案2】:

      迁移通常最适合数据库架构更改。

      来自docs(强调我的):

      迁移是一种随时间以一致且简单的方式更改您的数据库架构的便捷方式。 ...您可以将每次迁移视为数据库的新“版本”。

      这没有提到数据更新。仅架构更改。

      它们很容易对数据存储的数据造成严重破坏。优点是这是一个单向保险丝。一旦在数据库上运行,此迁移将永远不会再次运行。

      但是,更好的想法可能是创建一个完成相同数据迁移的幂等 rake 任务。

      让我们稍微扭转一下我们对这个问题的看法。也许我们可以只寻找没有学校信息的用户。然后我们只需要检索和更新这些用户。我们可以忽略所有其他用户。

      一个示例 rake 任务是(假设您在用户上有一个 id 字段):

      namespace :remove_nulls_from_user_schools do
        User.where(school: nil).each do |user|
          user.school = 'None'
          if user.save
            puts "Updated school for user with id: #{user.id}"
          else
            puts "Update Failed for user with id: #{user.id}"
          end
        end
      end
      

      这个 rake 任务具有可重新运行的额外好处(但是,它不是完全幂等的)。如果在学校字段为空的情况下生成了更多用户,您可以重新运行此 rake 任务并修复任何新用户。

      根据您要更新的用户数量,您可能希望使用 User.find_each 之类的内容来遍历用户。

      如果您要更新大量用户,您还可以使用上一个答案在 rake 任务中提供的 sql。这将是一个非常快速的 rake 任务,可以实现相同的目标:

      namespace :remove_nulls_from_user_schools do
        ActiveRecord::Base.connection.execute('update users set school='None' where school is null')
      end
      

      有关执行原始 sql 的更多信息,请参阅Rails 3 execute custom sql query without a model

      【讨论】:

        猜你喜欢
        • 2021-08-27
        • 1970-01-01
        • 1970-01-01
        • 2022-08-18
        • 1970-01-01
        • 2015-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多