I'm very happy to announce that Rails 4.0 now supports PostgreSQL array types. You can easily create a field of an array type in migration through: array => true. You can also add other options when you create fields of an array type (Length,default, and so on)
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 =>
# char varying [] end
Note that when you set the default value for a field that is an array type, you should use the notation in PostgreSQL ({value,another value}), and if you want to set the field default value of the column type to an empty array, you should: Default => ' {} '
Create_table:table_with_arrays do |t|
T.integer:int_array,: Array => true,:d efault => ' {} '
# integer[], default = []
T.integer:int_array,: A Rray => True,: Length => 2,:d efault => ' {1} '
# smallint[], default = [1]
End
examples of using PostgreSQL arrays in model
We now have a user model that contains first_name, last_name, nickname, where the nickname field is an array type. The following migration code creates the corresponding table:
Create_table:users do |t|
T.string:first_name
t.string:last_name
t.string:nicknames,: Array => true
end
And for this table, we have a simple model
Class User < ActiveRecord::Base
Attr_accessible:first_name,: last_name,: Nicknames
end
We do not use the default value for the field, if we instance a user object, the code is like this.
John = User.create (: first_name => ' John ',: last_name => ' Doe ')
If we call John.nickname, the result returns nil, and a null value is stored in PostgreSQL.
We can use the following code to set the nickname property value at the time of creation
John = User.create (: first_name => ' John ',: last_name => ' Doe '
: Nicknames => [' Jack ', ' Johnny '])
If we get records from the database, then the Nick_name field will turn into an array instead of returning the string {Jack, johnny}!. Rails 4.0 has a pure Ruby array converter, but if you want to accelerate the conversion process, you can use the Pg_array_parser gem mentioned earlier. Pgarrayparser has a C-based extension and a JRuby Java implementation (even if the gem now has some problems on the JRuby, I'm trying to solve it.) )
One key point to note is when interacting with a model and an array (or other variable values). ActiveRecord now does not track "destructive," or where the change occurred. This includes the push and pop operations of the array. If you need to use the "destructive" update, you must use the call< attribute >_will_change! This will let ActiveRecord know that you need to change the value of the property. For our user model, if you want to append elements after nickname, you can do this:
John = User.first
john.nicknames + = [' Jackie boy ']
# or
john.nicknames = John.nicknames.push (' Jackie boy ') c4/># at any time, the property is assigned by "=" and ActiveRecord tracks the change
john.save
john.reload
john.nicknames
#=> [' Jack ', ' Johnny ', ' Jackie Boy ']
john.nicknames.pop
john.nicknames_will_change!
# ' #pop ' operation will change the value of the array, so we need to tell ActiveRecord it will change
john.save
The last thing to use in PostgreSQL is to note that the array has no element limit, can be a multidimensional array, but when using multidimensional arrays, the number of child array elements must be the same.
[[1,2,3], [2,3,4], [4,5,nil]]
# available in PostgreSQL, same number of elements per sub array
[1,2,[3,4]]
# unavailable Array