Rails集合排序无法与UTF-8字符串一起使用

Ste*_*min 5 ruby postgresql ruby-on-rails ruby-on-rails-4

Rails集合排序不适用于UTF-8字符串:

> University.order('abbr asc').map(&:abbr)
=> ["?", "?", "?"]
Run Code Online (Sandbox Code Playgroud)

它应该是

> University.order('abbr asc').map(&:abbr)
=> ["?", "?", "?"]
Run Code Online (Sandbox Code Playgroud)

我想念什么?

带有ruby 2.1.5p273的Rails 4.1.8(2014-11-13修订版48405)[x86_64-darwin14.0]

Cas*_*per 5

这很可能是PostgreSQL 的排序规则设置问题

归类功能允许按列甚至按操作指定数据的排序顺序和字符分类行为。这减轻了数据库创建后不能更改LC_COLLATE和LC_CTYPE设置的限制。

您可以尝试通过Rails迁移修复列的排序规则。像这样:

class FixCollationForAbbr < ActiveRecord::Migration
  def up
    execute 'ALTER TABLE universities ALTER COLUMN abbr TYPE varchar COLLATE "ru_RU";' 
  end
end
Run Code Online (Sandbox Code Playgroud)

您可能还应该将归类信息添加到您的database.yml

defaults: &defaults
  adapter: postgresql
  encoding: utf8
  collation: ru_RU.utf8
  ctype: ru_RU.utf8
Run Code Online (Sandbox Code Playgroud)

database.yml设置如何影响使用PostgreSQL创建表的方式

def create_database(name, options = {})
  options = { encoding: 'utf8' }.merge!(options.symbolize_keys)

  option_string = options.inject("") do |memo, (key, value)|
    memo += case key
    ...snip...
    when :encoding
      " ENCODING = '#{value}'"
    when :collation
      " LC_COLLATE = '#{value}'"
    when :ctype
      " LC_CTYPE = '#{value}'"
    ...snip...
    end
  end

  execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
end
Run Code Online (Sandbox Code Playgroud)