另一种语言的字符数据类型

Data type for characters in another language

我在 activerecord 中有一个 Location table,其中包含 string 类型的列 address。我想将此 Garden Village Restaurant-B مطعم حديق فيلاو sub-B 存储在 address 列中,我应该使用哪种数据类型? 我已经尝试过 text 数据类型,但每当我尝试存储它时都会出现错误:

ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect string value: '\xD9\x85\xD8\xB7\xD8\xB9...' for column 'address'

或者,如果有其他方法,我愿意接受建议。

您可以 运行 在您想要的 table(s) 上执行以下命令:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

也先从table中删除所有数据 希望对您有所帮助!

生成迁移:(为什么?- 不要 运行 对您的数据库进行自定义查询,因为它们未记录在您的模式中)

rails g migration change_collation

在生成的迁移中添加如下代码。这将更改数据库的字符集(因此下一次迁移将自动遵循新的排序规则)并将更改现有表的字符集。

class ChangeCollation < ActiveRecord::Migration[5.0]
  def change_encoding(encoding,collation)
    connection = ActiveRecord::Base.connection
    tables = connection.tables
    dbname =connection.current_database
    execute <<-SQL
      ALTER DATABASE #{dbname} CHARACTER SET #{encoding} COLLATE #{collation};
    SQL
    tables.each do |tablename|
      execute <<-SQL
        ALTER TABLE #{dbname}.#{tablename} CONVERT TO CHARACTER SET #{encoding} COLLATE #{collation};
      SQL
    end
  end

  def change
    reversible do |dir|
      dir.up do
        change_encoding('utf8', 'utf8_unicode_ci')
      end
      dir.down do
        change_encoding('latin1', 'latin1_swedish_ci')
      end
    end
  end
end

此外,我认为 utf8_general_ci 也将支持存储乌尔都语字符。但基于 this post,最好继续使用 utf8_unicode_ci

另一种方式:加密保存地址:

config/initializers/encrypter.rb

encrypter_key = ActiveSupport::KeyGenerator.new('mypassword').generate_key('a..z', 32)
ENCRYPTER_CRYPT = ActiveSupport::MessageEncryptor.new(encrypter_key)

模型中:

class Location < ApplicationRecord
  before_save :encrypt_address
  def encrypt_address
    self.address = ENCRYPTER_CRYPT.encrypt_and_sign(self[:address]) if self[:address].present?
  end

  def address
    # override getter to decrypt and give original urdu string.
    ENCRYPTER_CRYPT.decrypt_and_verify(self[:address]) if self[:address].present?
  end
end