【问题标题】:Migrate Rails table from belongs_to to has_and_belongs_to_many将 Rails 表从 belongs_to 迁移到 has_and_belongs_to_many
【发布时间】:2016-05-28 21:35:21
【问题描述】:

目前,我有一个包含client_idusers 表(所以,一个User belongs_to :client)。

我们需要支持与一个用户关联的多个客户端,因此我们实现了User has_and_belongs_to_many :clients 关联。为此,我们:

  • 创建了一个新的clients_users 表,其中包含user_idclient_id 列;
  • users 中删除了client_id

现在,我们如何为我们最初在users 表中的每个client_id 自动创建HABTM 记录?我们不想丢失数据。

我不知道从哪里开始,因为 db:migrate 不应该涉及模型或它们之间的关联,并且在我的情况下执行原始查询可能会变得复杂。

【问题讨论】:

  • 我不明白您如何拥有回滚功能。您进行了更改,然后User 有 2 个Client,其 id 为 2 和 4。您将如何将其回滚到用户的 belongs_to 中?
  • 最初,所有在client_id 中有内容的用户将只有一个关联的HABTM 客户端。为什么他们会有 2 个客户?
  • 因为有人用过系统,给了他们2,然后说一周后你想回滚。你会丢失数据。
  • 好的,我明白了。你说得对。将从我的问题中删除回滚部分。

标签: ruby-on-rails postgresql database-migration


【解决方案1】:

只需将新的 has_and_belongs_to_many 关联添加到 UserClient 模型并运行以下迁移。

此解决方案来自http://manuelvanrijn.nl/blog/2013/03/04/rails-belongs-to-to-has-many/

class MultipleClientsForUser < ActiveRecord::Migration
  def up
    create_table :clients_users, id: false do |t|
      t.references :client, :user
    end

    # define the old belongs_to client associate
    User.class_eval do
      belongs_to :single_client, class_name: "Client", foreign_key: "client_id"
    end

    # add the belongs_to client to the has_and_belongs_to_many client
    User.find_each do |user|
      unless user.single_client.nil?
        user.clients << user.single_client
        user.save
      end
    end

    # remove the old client_id column for the belongs_to associate
    remove_column :users, :client_id
  end

  def down
    add_column :users, :client_id, :integer

    User.class_eval do
      belongs_to :single_client, class_name: "Client", foreign_key: "client_id"
    end

    #Note that only one client may be restored in rollback
    User.find_each do |user|
      user.single_client = user.clients.first unless user.clients.empty?
      user.save
    end

    drop_table :clients_users
  end
end

【讨论】:

  • 在迁移中使用模型是否安全?是否应该将所有内容都保存在一次迁移中?当某事失败时会发生什么?内容是否回滚并且列再次更改?
  • 在迁移中使用模型是否安全? - 这是一种常见的做法。是否应该将所有内容都保存在一次迁移中?我认为应该一步完成,一步回滚。当某事失败时会发生什么?迁移包含在事务中,因此如果出现故障,所有更改都会回滚。
  • @AndreiHorak,为了在迁移中使用模型时安全起见,您可以尝试这种方法blog.makandra.com/2010/03/…
  • class_eval 太过分了。 User.belongs_to ... 就好了。
猜你喜欢
  • 2011-09-27
  • 2014-02-28
  • 2020-10-28
  • 2011-05-21
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
相关资源
最近更新 更多