【问题标题】:Refactoring pseudo-enum models to enums将伪枚举模型重构为枚举
【发布时间】:2022-01-16 15:48:32
【问题描述】:

我有一个名为article_status 的模型,它只是为文章提供状态。我想删除这个article_status 表并直接在article 模型中使用enum

所以,我创建了一个新的迁移,但我的问题是如何编写 SQL 来更新列。

class AddStatusToArticles < ActiveRecord::Migration[6.1]
  def change
    add_column :articles, :status, :integer
    add_index :articles, :status

    execute <<~SQL
      # Write SQL here
    SQL

    change_column :articles, :status, :integer, null: false
  end
end

对于 SQL 部分,我想要相当于:

Article.all.each do |article|
  article.update_columns(status: article.article_status.name.parameterize.underscore)
end

在我的article 模型中:

enum status: { draft: 0, in_review: 1, reviewed: 2, published: 3, deleted: 4 }, _default: :draft

我像这样添加了enum

PS:我使用 Postgres 作为我的数据库。

【问题讨论】:

  • 表中有多少条记录?将逻辑转换为纯 SQL 真的值得吗?旧表中是否只有五个不同的值,还是 SQL 也需要能够处理其他值?
  • @spickermann 我有belongs_to 关联和一些我想删除的验证。如果我删除它并像上面那样编写特定于 ruby​​ 的代码,它会引发一个错误,提示未定义方法 article_status_id。它的记录很少,但由于这个错误,我选择了 SQL。它只有五个不同的值。
  • 如果你已经删除了article_status_id,你怎么知道什么状态属于什么文章?那如何在 SQL 中解决呢?
  • 我没有删除article_status_id 列,也没有删除article_status 表。我刚刚删除了特定于 Rails 的代码。 belongs_to :article_status。通过这样做并编写 Rails 逻辑而不是 SQL,我得到了第一条评论中提到的错误。

标签: sql ruby-on-rails ruby postgresql


【解决方案1】:

我会这样做:

statuses = ArticleStatus
  .pluck(:id, :name)
  .map { |(id, name)| [id, name..parameterize.underscore] }
  .to_h

Article.find_each do |article|
  article.update_columns(status: statuses[article. article_status_id])
end

【讨论】:

    猜你喜欢
    • 2023-02-21
    • 1970-01-01
    • 2012-08-31
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多