如何创建将所有图像从一个表传输到另一个表的Rails迁移?

时间:2014-01-31 13:53:23

标签: ruby-on-rails ruby rails-migrations

我正在创建一个迁移,它将执行以下三项操作:创建一个名为images的表,将所有图像从products表传输到新的images表,然后从products表中删除所有图像列。

除传输图像部分外,一切正常。没有图像信息传输。

以下是迁移:

class CreateImages < ActiveRecord::Migration
  def change
    create_table :images do |t|
      t.belongs_to :product
      t.string :image_file_name, :image_content_type
      t.integer :image_file_size
      t.boolean :main, :default => false

      t.timestamps
    end

    Product.all.each do |product|
      begin
        product.images.create(:image => product.image, :main => true)
      rescue => e
        logger.warn "Error while transferring images from product: #{product.name} to Images: #{e}"
      end
    end

    remove_column :products, :image_file_name
    remove_column :products, :image_content_type
    remove_column :products, :image_file_size
    remove_column :products, :image_updated_at

    add_index :images, [:product_id, :main]
  end
end

1 个答案:

答案 0 :(得分:2)

您不应该在ActiveRecord迁移中执行文件处理等文件系统操作。这主要是因为ActiveRecord迁移是在数据库事务中执行的,如果是事务文件,对文件的更改将不会被推送降压。另外,如果您尝试处理大量文件,可能会遇到数据库的意外连接超时或类似错误。

您必须在lib目录中创建一个Rake任务,并在迁移完成后运行它。这样的rake任务应该首先将文件复制到新目录,然后删除旧文件。您可能会发现这篇文章有用:http://fernandomarcelo.com/2012/05/paperclip-how-to-move-existing-attachments-to-a-new-path/。它不是特定于回形针的。

最后,在不同的迁移中运行remove_column语句。

class CreateImages < ActiveRecord::Migration
  def change
    create_table :images do |t|
      t.belongs_to :product
      t.string :image_file_name, :image_content_type
      t.integer :image_file_size
      t.boolean :main, :default => false

      t.timestamps
    end
  end
end

在此处手动运行您的任务。

最后,执行以下迁移。

class RemoveImagesFromProducts < ActiveRecord::Migration

  def change
    remove_column :products, :image_file_name
    remove_column :products, :image_content_type
    remove_column :products, :image_file_size
    remove_column :products, :image_updated_at

    add_index :images, [:product_id, :main]
  end
end