2009-04-08 57 views
2

我需要爲圖像文件的表創建AR遷移。圖像正被檢入到源代碼樹中,並應該像attachment_fu文件一樣。既然如此,我在/ public/system下爲它們創建了一個層次結構。如何使用Rails ActiveRecord遷移將主鍵插入MySQL數據庫?

由於attachment_fu生成鏈接的方式,我需要使用目錄命名約定來插入主鍵值。如何覆蓋MySQL的自動遞增以及任何Rails的魔法,這樣我可以做這樣的事情:

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

回答

2

哎呀,不愉快的問題有。我能想到的最簡單的方法是在你的遷移中有一些代碼通過attachment-fu實際「上傳」所有文件,因此讓插件創建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 

一看附件福的測試可能是有用的。

1

不像,說的Sybase,MySQL中,如果您指定在INSERT語句的列的ID列列表中,您可以在ID中插入任何有效的,不重複的值。不需要做特別的事情。

我懷疑rails的魔術只是爲了不讓rails知道id是自動遞增的。如果這是你插入這個表的唯一方法,那麼不要使id爲auto_increment。只要在一個int not null主鍵。

雖然坦率地說,這是使用一個密鑰作爲數據,所以它讓我感到不安。如果attachment_fu只是在尋找名爲「id」的,那麼創建一個名爲id的列,它是真正的數據,並將名爲「actual_id」的列作爲實際的合成auto_incremented鍵。

+0

不幸的是,我沒有時間去替換attachment_fu。我同意使用主鍵字段來構建文件路徑有點不便。 – 2009-04-08 04:28:56

+0

我覺得我遇到了Rails的魔法,而不是MySQL的魔法。 – 2009-04-08 04:32:20

0

這裏是我的克魯格:

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 
+0

這看起來確實做了什麼默認的主鍵...有什麼區別的功能? – 2009-04-09 07:34:23

0

我不完全確定我明白你爲什麼需要這樣做,但是如果您只需要一次性完成此操作,那麼只需在遷移中使用execute來設置ID(假設它尚未採取的,這是我無法想象它會):

執行 「插入圖片(ID,文件名)VALUES(42, 'foo.jpg')」

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}")

希望這有助於。

1
image = Image.create(:filename => "foo.jpg") { |r| r.id = 42 }