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

时间:2017-10-26 06:56:54

标签: ruby-on-rails activerecord sqldatatypes mysql2

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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也支持存储urdu字符。但基于this post,最好继续使用utf8_unicode_ci

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

配置/初始化/ 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

答案 1 :(得分:0)

您可以在所需的表上运行以下命令:

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

同时从该表中删除所有数据 希望它有所帮助!