2016-10-08 68 views
0

我正在更改現有應用程序中使用STI擴展的基本模型的inheritance_column值。如何編寫遷移以使現有列符合新的inheritance_columnRails inheritance_column migration

這是我第一次嘗試:

class MigrateStoryTypes < ActiveRecord::Migration 

    def self.up 
    Story.all.each { |story| 
     new_story_type = story.story_type.camelize + 'Story' 
     puts "changing #{story.id}'s story_type from #{story.story_type} to #{new_story_type}" 
     story.update_column :story_type, new_story_type 
    } 
    end 

    def self.down 
    Story.all.each { |story| 
     new_story_type = story.story_type.underscore.gsub /_story/, '' 
     puts "changing #{story.id}'s story_type from #{story.story_type} to #{new_story_type}" 
     story.update_column :story_type, new_story_type 
    } 
    end 

end 

然而,這種失敗:

的ActiveRecord :: SubclassNotFound:單表繼承機制 未能找到該子類: 'clean_slate'。由於列'story_type'被保留用於存儲繼承的 類中的類,因此此錯誤被提出 。如果您不打算使用 來存儲繼承類或覆蓋 Story.inheritance_column以使用該信息的另一列,請重命名此列。

是否有直接通過ActiveRecord執行此操作的方法,還是需要使用臨時列,SQL等?

+1

因此,您已經有一個'story_type'列,其中包含類名稱的下劃線版本(即''clean_slate''),現在您想將其移至STI,使用'story_type'作爲STI列,並將'story_type'的值給類名?你目前有多少個'story_type'值? –

+0

@ muistooshort正是。我目前有兩個'story_type'值。 – pdoherty926

回答

1

在遷移中使用模型通常是一個壞主意,因爲模型類假定他們知道數據庫結構是什麼,但遷移是爲了操縱數據庫結構。您的錯誤消息只是模型類不與數據庫同步的一種情況。 Story.all試圖實例化一個模型,你會得到你的ActiveRecord::SubclassNotFound STI異常,因爲ActiveRecord希望在story_type中找到類名,但仍舊有舊的字符串類型story_type:在數據庫不存在之前,無法使用模型修復數據庫固定。

我建議你假裝你的模型在遷移中根本不存在,如果你直接使用數據庫,你會有更好的時間。你只有兩個story_type值,所以SQL是非常簡單的:

def up 
    connection.execute(%q{ 
    update stories 
    set story_type = case story_type 
     when 'whatever1' then 'Whatever1Story' 
     when 'whatever2' then 'Whatever2Story' 
    end 
    }) 
end 

這裏只有兩個值,你知道他們,所以不要浪費時間巧言令色。

+0

很多好的建議在這裏。謝謝! – pdoherty926