2014-06-19 54 views
7

這裏是我的schema.rb軌道4遷移:Mysql2 ::錯誤:數據太長,列「XXXX」

create_table "users", force: true do |t| 
    t.string "name",  limit: 6 
    t.string "email" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

我設置FO字符串列「名」的限制。

然後,在控制檯:

user = User.new(name:"1234567890",email:"[email protected]") 
user.save! 

它引發的錯誤:

ActiveRecord::StatementInvalid: Mysql2::Error: Data too long for column 'name' at row 1: INSERT INTO `users` (`created_at`, `email`, `name`, `updated_at`) VALUES ('2014-06-19 15:08:15', '[email protected]', '1234567890', '2014-06-19 15:08:15') 

但是,當我切換到軌道3

我發現它截斷字符串 「」 自動,並將其插入 「」 到數據庫沒有錯誤。

有沒有什麼關於這個已被刪除rails 4

我應該自己在模型中添加一些截斷函數嗎?謝謝!

+1

對於最後一個問題,它可能取決於你的使用情況爲'User'創作。也許最好在':name'上添加一個驗證器來檢查長度,如果用戶結束時間過長,會向用戶顯示一個錯誤? –

+0

驗證可能是要走的路,因爲用戶應該知道他們的名字不能超過6個字符。否則,當他們進入「喬納森」時他們可能會感到驚訝,但當他們看着他們的個人資料時,他們的名字被列爲「喬納特」。 –

+0

謝謝,我明白更好的方法是添加一些驗證。但是我只想弄清楚Rails 4中發生了什麼變化,並且我有一些模型對用戶是不可見的,所以在這種情況下,驗證無法幫助我。 – tzzzoz

回答

16

你所看到的是MySQL中的差異,而不是Rails。默認情況下,MySQL會截斷太長的數據,而不會引發錯誤。如果您將MySQL設置爲strict模式,它將引發錯誤而不是以靜默方式截斷數據。

默認情況下版本爲4,Rails turns on strict mode。這就是爲什麼你看到與Rails 3不同的行爲。這你可能想要的行爲。無聲地截斷數據幾乎總是很糟糕,並可能導致用戶非常混淆的行爲。

如果你真的要截斷數據,你可以turn off strict mode或使用之前過濾器:

before_save :truncate_username 
def truncate_username 
    self.username = username.slice(0, 6) 
end 
+0

謝謝,這很有幫助!救命稻草 – tzzzoz

7

我偶然發現this article恰好在幾天前寫的。

主要關心的問題是這樣的:

...I recently upgraded from rails 3.2 to rails 4.0. They implemented a major change with ActiveRecords that I can find no mention of any where except in the source and change log.

  • mysql and mysql2 connections will set SQL_MODE=STRICT_ALL_TABLES by default to avoid silent data loss. This can be disabled by specifying strict: false in your database.yml .

這似乎解釋了爲什麼你停止接受的錯誤,當你恢復到Rails的3.您可以在MySQL connection adapter module選項看到這一點,並它看起來像是4.1.2候選版本的added way back in May 2012(如果我正確讀取標籤)。

此人通過解決了他們的問題... [固定]代碼要麼具有適當的字段長度,要麼手動截斷數據...

就你而言,你可以通過在database.yml中添加strict: false來解決你在Rails 4中的問題。如果您想自定義數據的截斷方式,我同意JKen13579對before_save回調的建議。否則,從我所看到的情況來看,它似乎會截斷最右側的字符,所以如果這樣就足夠了,那麼您可能會忽略默認的截斷行爲。

+1

謝謝,這對我來說很清楚! – tzzzoz

+1

這個答案不僅指向一個實際解釋真正問題的文章,在閱讀它之後,您還可以看到爲什麼在遷移時自己切片數據同樣糟糕。很好的答案@ paul-richter – josethernandezc