我有一个非常简单的rails页面,显示“项目”,其中包含标题,年份和与之关联的文件。这是我的控制器:
# GET /projects
# GET /projects.json
def index
@projects = Project.all.order(:title)
end
这是index.html.erb:
<ul>
<% @projects.each do |project| %>
<li><a href="<%= project.document.url %>" target="_blank"><em><%= project.title %></em>, <%= project.year %></a>
<% if logged_in? %>
<br><%= link_to 'Edit', edit_project_path(project) %> / <%= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
</li>
<% end %>
<% if logged_in? %>
<li><%= link_to 'New Project', new_project_path %><p id="notice"><%= notice %></p></li>
<% end %>
</ul>
在Heroku上使用psql(10.3,服务器9.6.2)
除了名为“Spring House”,“Springg House”,Springgg House,等等的所有结果之外,所有结果都按字母顺序完美排序。其他使用此模式的标题排序正确,但出于某种原因, “春天”没有。
对于我应该在应用中查找的内容,您有什么建议吗?
感谢您的帮助!
答案 0 :(得分:1)
这是一个&#34;功能&#34; Postgresql如何处理排序 - 更糟糕的是,它因数据库而异,甚至从平台到平台。
当您编写Project.all.order(:title)
时,Rails会生成SQL(正如您在上面的评论中正确指出的那样),如下所示:
SELECT "projects".* FROM "projects" ORDER BY "projects"."title" ASC
这会留下Postgresql或您正在使用的任何其他数据库来确定订单。 Postgresql使用collations来确定顺序,这是依赖于语言环境的。通过在\l
中执行psql
命令,可以查看数据库正在使用的归类。例如,在我的机器上,我的数据库默认为en_US.UTF-8
。
这里变得棘手。我在postgres中创建了一个表格如下:
CREATE TABLE sorttest (name text);
INSERT INTO sorttest VALUES ('Spring House');
INSERT INTO sorttest VALUES ('Springg House');
INSERT INTO sorttest VALUES ('Springgg House');
SELECT * FROM sorttest ORDER BY name ASC;
在我的Mac(Mac OS 10.13.3)上,它返回
name
----------------
Spring House
Springg House
Springgg House
然而,在我的Debian机器上,它返回
name
----------------
Springgg House
Springg House
Spring House
据我所知,Mac实际上是#34;做错了#34;虽然它是你想要的结果。我的Debian盒子和你的Heroku dyno按照UTF-8规范排序:忽略空格和大小写,&#34; springgghouse&#34;应该来到#spring;&#34;。
如果要使用其他排序规则进行排序(例如,&#34; C&#34;或&#34; POSIX&#34;排序规则),则需要使用如下SQL命令:
SELECT "projects".* FROM "projects" ORDER BY "projects"."title" COLLATE "C" ASC
幸运的是,你可以使用ActiveRecord实现目标:
Project.all.order('title COLLATE "C"')
但是,请注意,这将使您的排序顺序成为大写字母 - &#34; C&#34; collation比较ASCII字节值,因此大写字母将在小写字母之前排序,例如:
SELECT * FROM sorttest ORDER BY name COLLATE "C" ASC;
name
----------------
Spring House
SpringGg House
Springg House