2

我需要为图像文件表创建 AR 迁移。图像被检入到源代码树中,并且应该像 attachment_fu 文件一样工作。既然如此,我正在 /public/system 下为它们创建一个层次结构。

由于 attachment_fu 生成链接的方式,我需要使用目录命名约定来插入主键值。如何覆盖 MySQL 中的自动增量以及任何 Rails 魔法,以便我可以执行以下操作:

image = Image.create(:id => 42, :filename => "foo.jpg")
image.id #=> 42
4

6 回答 6

2

哎呀,这不是一个令人愉快的问题。我能想到的最简单的方法是在您的迁移中添加一些代码,这些代码实际上通过附件“上传”所有文件,因此让插件创建 ID 并放置文件。

像这样的东西:

Dir.glob("/images/to/import/*.{jpg,png,gif}").each do |path|

  # simulate uploading the image
  tempfile = Tempfile.new(path)
  tempfile.set_encoding(Encoding::BINARY) if tempfile.respond_to?(:set_encoding)
  tempfile.binmode
  FileUtils.copy_file(path, tempfile.path)

  # create as you do in the controller - may need other metadata here
  image = Image.create({:uploaded_data => tempfile})
  unless image.save
    logger.info "Failed to save image #{path} in migration: #{image.errors.full_messages}"
  end

  tempfile.close!
end

看看attachment-fu 的测试可能会有用。

于 2009-04-08T17:22:42.460 回答
1

与 Sybase 不同,在 MySQL 中,如果在插入语句的列列表中指定 id 列,则可以在 id 中插入任何有效的、非重复的值。不需要做一些特别的事情。

我怀疑 rails 的魔法只是不让 rails 知道 id 是自动递增的。如果这是您插入此表的唯一方法,则不要将id设为 auto_increment。只需输入一个 int 非空主键。

虽然坦率地说,这是使用密钥作为数据,所以这让我感到不安。如果 attachment_fu 只是在寻找名为“id”的,则将名为 id 的列设为真正的数据,并将名为“actual_id”的列设为实际的、合成的、auto_incremented 键。

于 2009-04-08T04:04:40.790 回答
1
image = Image.create(:filename => "foo.jpg") { |r| r.id = 42 }
于 2010-06-10T22:51:24.550 回答
0

这是我的kluge:

class AddImages < ActiveRecord::Migration
  def self.up
    Image.destroy_all

    execute("ALTER TABLE images AUTO_INCREMENT = 1")

    image = Image.create(:filename => "foo.jpg")
    image.id #=> 1
  end

  def self.down
  end
end
于 2009-04-08T04:31:25.607 回答
0

我不完全确定我理解你为什么需要这样做,但如果你只需要这样做一次,对于迁移,只需execute在迁移中使用来设置 ID(假设它还没有被占用,我可以'没想到会是):

执行“插入图像(id,文件名)值(42,'foo.jpg')”

于 2009-04-08T22:44:52.453 回答
0

我同意 AdminMyServer 虽然我相信您仍然可以直接在对象上执行此任务:

image = Image.new :filename => "foo.jpg"
image.id = 42
image.save

您还需要确保在流程结束时更新您的 id 自动增量,以避免将来发生冲突。

newValue = Images.find(:first, :order => 'id DESC').id + 1
execute("ALTER TABLE images AUTO_INCREMENT = #{newValue}")

希望这可以帮助。

于 2009-04-20T02:19:52.503 回答