【问题标题】:rails update_all returns unknow column * in field listrails update_all 在字段列表中返回未知列 *
【发布时间】:2019-11-08 14:57:50
【问题描述】:

我有这个迁移任务:

owner = Owner.first
Factory.update_all(original_owner: owner)

它返回一个错误:

ActiveRecord::StatementInvalid (Mysql2::Error: Unknown column 'factories.original_owner' in 'field list': UPDATE `factories` SET `factories`.`original_owner` = 1)

我很确定该专栏就在那里。创建该列的迁移已成功运行,我在控制台中进行了检查。

我能够运行以下任务:

Factory.all.each { |c| c.update(original_employee: c.employee) }

但是,这需要很长时间,因为它会遍历整个表。我想通过使用update_all 来优化迁移,因为有很多工厂属于同一所有者。

非常感谢任何信息/线索。

更新: 每个factory 都归owner 所有。 owner 可以是 personbotnil。为了优化迁移,工厂分为 3 组:

  • nil 拥有的工厂,可以跳过
  • person 拥有的工厂,我们可以使用 eachupdate 来更新原始所有者字段
  • bot 拥有的工厂,我们可以使用update_all

update_all 需要在所有者上显式调用id,即bot。如果尚未在数据库中创建 bot,这将导致 nil 头痛。由于nil.id 抛出异常并中断程序。

问题:我们使用 CircleCI 运行测试。这还没有测试数据库,所以botnil。如果我rails db:seed 它需要rails db:migraterails db:migrate 抛出nil 异常:(

【问题讨论】:

    标签: mysql ruby-on-rails migration


    【解决方案1】:

    试试:

    Factory.update_all(original_owner_id: owner.id)
    

    编辑:我的一位资深同事提出了一个更好的版本:

    Factory.where.not(owner: nil).update_all('original_owner_id = owner_id')
    

    为我们的案例定制:

    Factory.where.not(owner: [nil, 0]).update_all('original_owner_id = owner_id')
    

    因为查询 (Factory.where.not(owner: [nil,0]).to_sql) 查找 owner_id

    【讨论】:

    • 这救了我的命!
    • 我能再问你一些吗,我希望能够做到Factory.update_all(original_owner: owner),因为这可能会防止nil头痛(当前方法owner.id遭受nil异常) .请问为什么在each方法中,我可以使用owner对象而不是调用owner.id
    • 当然 - 当您调用 update_all 时,您会执行原始 SQL 查询 - 无论您要更新什么,都必须与数据库中的列名匹配。当工厂属于所有者时,本质上它在数据库中有一个 owner_id 列。虽然 rails 知道更新所有者确实意味着更新 owner_id,但 SQL 无法弄清楚
    • 问题是,为了优化迁移,我可以使用update_all,并为所有这些bot 创建的公司使用相同的所有者bot。但是,从技术上讲,bot 可能为 nil(例如,在测试数据库中),并且调用 owner.id 会破坏代码。不知何故eachupdate 摆脱了nil 的头痛,你有什么出路的建议吗?
    • 你能用你的完整迁移代码编辑这个问题吗
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 2015-05-18
    相关资源
    最近更新 更多