在除錯我的 Rails 應用程式時,我在日志檔案中發現了以下訊息:
(0.1ms) ROLLBACK
Completed 500 Internal Server Error in 25ms (ActiveRecord: 4.2ms)
ActiveRecord::StatementInvalid (Mysql2::Error: Incorrect string value: '\xF0\x9F\x98\x89 u...' for column 'description' at row 1: INSERT INTO `course` (`title`, `description`) VALUES ('sometitle', '<p>Description containing ?? and stuff</p>')
這似乎源于我的資料庫是帶有 not-quite-utf-8 的 MySQL:
CREATE TABLE `course` (
`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(250) DEFAULT NULL,
`description` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2080 DEFAULT CHARSET=utf8;
根據這個問題的答案CHARSET=utf8 只能處理 3 位元組字符,而不是 4 位元組字符。
Emoticon ?? 需要四個位元組 - 請參閱日志檔案中的 \xF0\x9F\x98\x89。
我對轉換整個資料庫持謹慎態度。我寧愿禁止使用表情符號和其他 4 位元組字符——它們在我的網站上確實沒有必要。
在 Rails 中執行此操作的最佳方法是什么?
uj5u.com熱心網友回復:
基于這些答案的正則運算式,我實作了一個驗證器:
# file /lib/three_byte_validator.rb
# forbid characters that use more than three byte
class ThreeByteValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value =~ /[\u{10000}-\u{10FFFF}]/
record.errors.add attribute, (options[:message] || 'Keine Emoticons, keine UTF-8 Zeichen mit 4 Byte')
end
end
end
現在我可以在首先出現問題的模型上使用這個驗證器:
class Course < ApplicationRecord
validates :title, length: { in: 3..100 }, three_byte: true
validates :description, length: { minimum: 50 }, three_byte: true
以及其他型號:
class Person < ApplicationRecord
validates :firstname, :lastname, :country, :city, :address, three_byte: true
uj5u.com熱心網友回復:
在 MySQL 中,Winking Face(和大多數其他表情符號)需要utf8mb4而不是utf8.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/441327.html
標籤:mysql 轨道上的红宝石 验证 UTF-8 utf8mb4
