我在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'
或者,如果还有其他方式,我愿意接受建议。
答案 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;
同时从该表中删除所有数据 希望它有所帮助!