脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Ruby - 简单介绍Ruby on Rails对PostgreSQL数组类型的支持

简单介绍Ruby on Rails对PostgreSQL数组类型的支持

2020-04-26 10:19脚本之家 Ruby

这篇文章主要介绍了简单介绍Ruby on Rails对PostgreSQL数组类型的支持,Rails框架从4.0以后对PG的数组提供了支持,需要的朋友可以参考下

 我非常高兴在宣布Rails 4.0 现在支持 PostgreSQL 数组类型. 你可以方便的在migration通过 :array => true里创建数组类型的字段. 创建数组类型的字段的时候还可以添加其它的选项(length,default,等等)
 

?
1
2
3
4
5
6
7
8
create_table :table_with_arrays do |t|
 t.integer :int_array, :array => true
 # integer[]
 t.integer :int_array, :array => true, :length => 2
 # smallint[]
 t.string :string_array, :array => true, :length => 30
 # char varying(30)[]
end

需要注意在是对数组类型的字段设置默认值的时候,你应该用Postgresql里的写法({value,another value}), 如果你想设置数组类型的字段默认值为空数组的时候,你应该使用:default => '{}'
 

?
1
2
3
4
5
6
create_table :table_with_arrays do |t|
 t.integer :int_array, :array => true, :default => '{}'
 # integer[], default == []
 t.integer :int_array, :array => true, :length => 2, :default => '{1}'
 # smallint[], default == [1]
end


在Model里使用Postgresql数组的例子

我们现在有个包含first_name, last_name, nickname的user model, 其中nickname字段是数组类型. 下面的migration代码会创建相应的表:
 

?
1
2
3
4
5
create_table :users do |t|
 t.string :first_name
 t.string :last_name
 t.string :nicknames, :array => true
end

并且对于这个表,我们有个简单的model
 

?
1
2
3
class User < ActiveRecord::Base
 attr_accessible :first_name, :last_name, :nicknames
end

我们没有对字段使用默认值,如果我们实例一个User 对象,代码是这样的.
 

?
1
john = User.create(:first_name => 'John', :last_name => 'Doe')

如果,我们调用john.nickname, 结果会返回nil, 并且在postgreSQL 里存储的是NULL值.

我们通过下面的代码可以在创建时,设置nickname属性值 
 

?
1
2
john = User.create(:first_name => 'John', :last_name => 'Doe',
 :nicknames => ['Jack', 'Johnny'])

如果我们从数据库获取记录,那么nick_name字段会转变成一个数组,而不是返回字符串{Jack, Johnny}!。Rails 4.0拥有一个纯Ruby数组转换器,但是如果你想让转换过程加速,那么就可以使用之前提到的 pg_array_parser gem。PgArrayParser 拥有一个基于C的扩展,还有一个JRuby的Java的实现(即使这个gem现在在JRuby上存在些问题,我正在尝试去解决这个问题。)

有一个重点需要注意的,就是当在一个model中和数组(或者其他可变数值)交互的时候。ActiveRecord现在并没有跟踪"destructive",或者更改发生的地方。这包括数组的push和pop操作。如果你需要使用"destructive"更新,你必须使用call<属性>_will_change!这样可以让ActiveRecord知道你需要更改属性的值。对于我们的这个User model,如果你想在nickname后面追加元素,你可以这样做:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
john = User.first
 
john.nicknames += ['Jackie boy']
# 或者
john.nicknames = john.nicknames.push('Jackie boy')
# 任何时候,属性通过"="赋值,ActiveRecord会跟踪这个更改
john.save
 
john.reload
john.nicknames
#=> ['Jack', 'Johnny', 'Jackie Boy']
 
john.nicknames.pop
john.nicknames_will_change!
# '#pop'操作会改变数组的值,所以我们需要告诉ActiveRecord它将会发生更改
john.save

 

最后一项在Postgresql中使用数组要注意的事情是: 数组没有元素数量限制,可以是多维数组,但是在使用多维数组时, 子数组元素个数必须是一样的.

 

?
1
2
3
4
5
[[1,2,3], [2,3,4], [4,5,nil]]
# 在PostgreSQL 可用,每个子数组元素个数一样
 
[1,2,[3,4]]
# 不可用的数组

 

延伸 · 阅读

精彩推荐
  • Ruby剖析 Ruby 访问控制

    剖析 Ruby 访问控制

    前面,我们说 Ruby 没有函数,只有方法.而且实际上有不止一种方法.这一节我们介绍 访问控制 (accesscontrols). 想想当我们在最高层而不是在一个类的定义里定义...

    ruby教程网3572020-04-08
  • RubyRuby环境下安装使用bundler来管理多版本的gem

    Ruby环境下安装使用bundler来管理多版本的gem

    这篇文章主要介绍了Ruby环境下安装使用bundler来管理多版本的gem的方法,举了Ruby On Rails中的应用实例来进行演示,需要的朋友可以参考下 ...

    日拱一卒4332020-05-10
  • RubyCentOS中配置Ruby on Rails环境

    CentOS中配置Ruby on Rails环境

    经过一个上午的折腾,终于把ROR环境在CentOS中搞定,绕了很多弯路,把文章写下来总结一下 ...

    可乐加糖4762020-04-12
  • RubyRuby进行文件信息输出实例代码

    Ruby进行文件信息输出实例代码

    Ruby进行文件信息输出实例代码,数据是随机的,所以每次的记录都会不同。 ...

    ruby教程网2962020-04-10
  • RubyRuby设计模式编程中使用Builder建造者模式的实例

    Ruby设计模式编程中使用Builder建造者模式的实例

    这篇文章主要介绍了Ruby设计模式编程中使用Builder建造者模式的实例,建造者模式将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表...

    范孝鹏2192020-05-07
  • Ruby简要说明Ruby中的迭代器

    简要说明Ruby中的迭代器

    这篇文章主要介绍了Ruby中的迭代器,迭代器的概念在动态语言的编程中十分重要,文章中介绍了Ruby中的each迭代器和collect迭代器,需要的朋友可以参考下 ...

    goldensun2772020-04-25
  • RubyRuby迭代器的7种技巧分享

    Ruby迭代器的7种技巧分享

    这篇文章主要介绍了Ruby迭代器的7种技巧分享,Ruby中的迭代器非常人性化,本文既是讲解了7个技巧也是讲解了7种迭代器,需要的朋友可以参考下 ...

    脚本之家4782020-04-20
  • RubyRuby简洁学习笔记(一):字符串、数字、类和对象

    Ruby简洁学习笔记(一):字符串、数字、类和对象

    这篇文章主要介绍了Ruby简洁学习笔记(一):字符串、数字、类和对象,本文是学习笔记第一篇,需要的朋友可以参考下 ...

    脚本之家2472020-04-20