将raails表从belongs_to迁移到has_and_belongs_to_many

时间:2016-02-17 09:15:08

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

目前,我的> mydf country year x xfrequency xfreq 1 CAN 1990 1 1 1 2 CAN 1991 0 0 0 3 CAN 1992 1 2 3 4 CAN 1993 0 0 0 5 CAN 1994 2 4 5 6 CAN 1995 1 5 6 7 USA 1990 0 0 0 8 USA 1991 2 2 2 9 USA 1992 1 3 3 10 USA 1993 0 0 0 11 USA 1994 1 4 5 12 USA 1995 0 0 0 13 GER 1990 NA NA 0 14 GER 1991 1 1 1 15 GER 1992 0 0 0 16 GER 1993 1 2 3 17 GER 1994 2 4 4 18 GER 1995 1 5 5 表包含users(因此,client_id)。

我们需要支持与用户关联的多个客户端,因此我们已经实现了User belongs_to :client关联。为此,我们:

  • 创建了一个新的User has_and_belongs_to_many :clients表格,其中包含clients_usersuser_id列;
  • client_id移除了client_id

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

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

1 个答案:

答案 0 :(得分:6)

只需向has_and_belongs_to_manyUser模型添加新的Client关联,然后运行以下迁移。

此解决方案来自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