我如何使用 postgresql 对 Rails 4 中的 ip 地址进行排序

How i can sort ip address in Rails 4 using postgresql

我的 postgresql table 中有 "ip" 列,其中包含 ip 地址。我想按升序对这些 ip 地址进行排序。以下是数据示例

    147.226.211.40
    1.39.80.12
    128.237.199.43

结果应该是

    1.39.80.12
    128.237.199.43
    147.226.211.40

换句话说,如果 IP 地址是 a.b.c.d,则按 a、b、c、d 排序。

下面的模型不适用于我。

  default_scope { order('ip ASC') }

我该怎么做?

只是为了订购而转换为 inet:

ORDER BY ip::inet ASC

这应该有效:

default_scope { order('ip::inet ASC') }

或者,如果您的数据有问题,这可能会奏效,但如果不创建索引会非常慢:

ORDER BY regexp_replace(ip, '.?([3-9]\d{2}|25[6-9]|2[6-9]\d)', '')::cidr 

PostgreSQL 支持 inet 数据类型。使用正确的数据类型,许多问题就会消失。

scratch=# create table test (
scratch(# ip_addr inet not null);
CREATE TABLE
scratch=# insert into test values ('147.226.211.40');
INSERT 0 1
scratch=# insert into test values ('1.39.80.12');
INSERT 0 1
scratch=# insert into test values ('128.237.199.43');
INSERT 0 1
scratch=# select * from test order by ip_addr;
    ip_addr     
----------------
 1.39.80.12
 128.237.199.43
 147.226.211.40
(3 rows)

ActiveRecord支持inet数据类型。简单来说 。 . .

$ bin/rails generate scaffold IpAddr ip_addr:inet 

编辑控制器。按符号 :ip_addr.

排序
$ head -9 app/controllers/ip_addrs_controller.rb 
class IpAddrsController < ApplicationController
  before_action :set_ip_addr, only: [:show, :edit, :update, :destroy]

  # GET /ip_addrs
  # GET /ip_addrs.json
  def index
    @ip_addrs = IpAddr.all.order(:ip_addr)
    #                      ^^^^^^^^^^^^^^^
  end

浏览到该页面,您会发现 IP 地址排序正确。