Emoji
Bài đăng này đã không được cập nhật trong 9 năm
I. What is Emoji?
Emoji (絵文字= picture letter) là thuật ngữ xuất phát từ tiếng Nhật, có thể hiểu là những kí tự hình ảnh, ví dụ như hình mặt cười, biểu tượng cảm xúc như
II. Approach
Mysql 5.5.3+ hỗ trợ mã utf8mb4 để lưu Emoji
III. Implement
1. Config mysql server
Trước tiên là thiết lập 1 vài thông số character-set của mysql server trong file my.conf như sau:
# my.conf
[client]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-character-set-client-handshake
Sử dụng của sổ dòng lệnh của mysql tạo thử database và kiểm tra variables
mysql> use sample
Database changed
mysql> show variables like "char%" ;
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
Như bản variables trên ta thấy ngoại trừ character_set_filesystem và character_set_system thì tất cả giá trị của character-set còn lại đều là utf8mb4. Như vậy là đã hoàn thành xong thiết lập bên phái mysql server.
2. Config rails
Bước tiếp theo là config bên phái rails application. Trong file database.yml chúng ta thêm 3 thuộc tính charset, encoding, collaction như dưới đây để chỉ ra rằng chúng ta sẽ sử dụng mã utf8mb4.
development:
adapter: mysql2
charset: utf8mb4
encoding: utf8mb4
collation: utf8mb4_unicode_ci
reconnect: false
3. Max key length is 767 bytes problem
Mysql giới hạn kích thước của index key là 767 bytes. Với Utf8 sử dụng 3 bytes để mã hoá kí tự nên độ dài tối đa của index key là 255 kí tự. Nhưng Utf8mb4 sử dụng 4 bytes để mã hoá kí tự nên tối đa ta có 767/4 = 191 kí tự. Mà mặc định của khi tạo bảng với index kích thước tối đa của index key là 255 nên xảy ra lỗi như trên. Với rails 4 thì vấn đề này sẽ được giải quyết trọng vẹn, nhưng hiện tại chúng ta dùng rails 3 nên ta phải override một số hàm thư viện của ActiveRecord.
Override some module of ActiveRecord
// SchemaStatement
module ActiveRecord
module ConnectionAdapters # :nodoc:
module SchemaStatements
MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191
def initialize_schema_migrations_table
if @config[:encoding] == 'utf8mb4'
ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4)
else
ActiveRecord::SchemaMigration.create_table
end
end
end
end
end
// SchemaMigration
module ActiveRecord
class SchemaMigration < ActiveRecord::Base
def self.index_name
"#{Base.table_name_prefix}unique_schema_migrations#{Base.table_name_suffix}"
end
def self.create_table(limit=nil)
unless connection.table_exists?(table_name)
version_options = {null: false}
version_options[:limit] = limit if limit
connection.create_table(table_name, id: false) do |t|
t.column :version, :string, version_options
end
connection.add_index table_name, :version, unique: true, name: index_name
end
end
end
end
Config length for unique columns of table
Thay đổi giới hạn độ dài cho một số thuộc tính unique
// db/migrate/*.rb
add_index :users, :email, unique: true, length: 191
4. Fix json
Đối với những ứng dụng web yêu cầu dữ liệu trả về dưới dạng json, chúng ta cần override module sau để dữ liệu trả về đúng với mã utf8bm4.
module ActiveSupport
module JSON
module Encoding
class << self
def escape_with_json_gem(string)
::JSON.generate([string])[1..-2]
end
alias_method_chain :escape, :json_gem
end
end
end
end
IV. Conclusion
Cùng với sự phát triển mạnh mẽ của mạng xã hội và smartphone, Emoji là thứ ko thể thiếu, góp thêm phần thú vị hình tượng khi chúng ta giao tiêp và chia sẻ thông tin qua mạng. Và như hướng dẫn ở trên, ta có thể thấy việc tạo ra 1 ứng dụng web hộ trợ Emoji thật đơn giản với Ruby on rails.
All rights reserved