2015-02-10 102 views
0

我在我的postgresql表中包含ip地址的“ip”列。我想按升序对这些IP地址进行排序。下面是例如数据如何我可以使用postgresql在Rails 4中对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') } 

我该怎么办呢?

+0

IPv4地址实际上可以存储为32位整数。我想知道'1.39.80。,12.97'是什么。 – 2015-02-10 18:53:24

+0

这是我的错误,当提出问题。 – Kashiftufail 2015-02-10 18:58:42

+0

实际上,IPv4地址*是一个32位整数。 – 2015-02-11 22:28:38

回答

4

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地址的排序正确。

0

只投给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 
+0

错误是“PG :: InvalidTextRepresentation:错误:类型inet的无效输入语法:”12.33.44.555“:SELECT”ip_addresses“。* FROM”ip_addresses“ORDER BY IP :: inet ASC” – Kashiftufail 2015-02-10 19:03:08

+0

显然它不会工作if你的IP地址是无效的。 – 2015-02-10 19:05:53

+1

@ Kashiftufail:12.33.44.555不是有效的IP地址,您的输入有问题。至少你现在知道为什么你应该使用最匹配的数据类型和一些输入验证。 – 2015-02-10 19:07:32

相关问题