【问题标题】:Update a column, all rows更新一列,所有行
【发布时间】:2021-09-17 19:04:45
【问题描述】:

我在表中添加了一个新列,但我忘记添加 :default 选项。现在我想在每一行填充该列。

有没有办法使用控制台?过去一个小时我一直在谷歌搜索,但我找不到任何东西。

我知道如何对单个对象执行此操作,但不知道如何对模型的所有行执行此操作。

Foo.find(1).update_attribute(:myattribute, 'value')

【问题讨论】:

  • 您想为每一行分配相同的值还是为每行分配不同的值?
  • 所有值相同。谢谢
  • 好的,@petrov。你可以试试 update_all 方法

标签: ruby-on-rails


【解决方案1】:

试试这个:

Foo.update_all(some_column: "bar")

这将生成对数据库的 SQL 查询:

UPDATE "foos" SET "some_column" = "bar"; 

【讨论】:

  • 谢谢你 pake007。这行得通。最初我尝试了 ModelName.update 但它没有用
  • 没问题@Petrov,更重要的是,您可以将条件参数传递给此方法。比如: Foo.update_all({:new_column => "bar"}, {:old_column_1 => nil}) 。它将更新所有在 'old_column_1' 列上具有 nil 值的记录。
  • 但是对于 Rails 2.2?使用什么语法?
  • 在 rails 3 和 4 这个方法是 ActiveRecord::Relation 的成员,因此它可以与 where 的和朋友链接,像这样:Foo.where(old_column_1: nil).update_all(new_column: 'bar')
【解决方案2】:

由于您已经在之前的迁移中创建了新字段,请创建一个全新的迁移:

rails g migration UpdateFoos

修改迁移:

def self.up    
  say_with_time "Updating foos..." do
    Foo.find(:all).each do |f|
      f.update_attribute :myattribute, 'value'
    end
  end
end

# from command line
Rake db:migrate

让我知道这是否可行,它可能需要一些调整。有关更多信息,请参见 rails docs

【讨论】:

  • 很好的答案。 Rails3 人,在上面的例子中使用 Foo.all 而不是 Foo.find(:all)。
  • 虽然您对新迁移的看法是正确的,但如果您有很多列:每个列都是更新所有列的缓慢方法。 :update_all 会快很多。
【解决方案3】:

你可以这样做:

Foo.update_all(new_column: "bar")

【讨论】:

    【解决方案4】:

    当然你可以使用Foo.update_all(:myattribute => "value") 这样的smth,但它只会修改已经创建的数据。要为所有“未来”数据设置默认值,这是创建单独迁移的好方法,如下所示:

    rails generate migration AddDefaultValueToFoo
    

    像这样修改新的迁移(例如,myattribute 具有字符串类型):

    class AddDefaultValueToFoo < ActiveRecord::Migration
      def self.up
        change_column :foos, :myattribute, :string, :default => "value"
        Foo.update_all(:myattribute => "value")
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      相关资源
      最近更新 更多