Rails でPostgreSQLの配列型を試す
今回の仕事でPostgreSQLの配列(array)型を使えると便利なので試してみました。
Migration
Migration で Rails標準の型以外を使うには型の部分を文字列で指定します。
class CreateTodos < ActiveRecord::Migration def self.up create_table :todos do |t| t.date :due t.string :task t.column :opts, "integer[]" t.timestamps end end def self.down drop_table :todos end end
rake db:migrateすると無事に 配列型 カラムが出来ました。
> \d todos Table "public.todos" Column | Type | Modifiers ------------+-----------------------------+---------------------------------------------------- id | integer | not null default nextval('todos_id_seq'::regclass) due | date | task | character varying(255) | opts | integer[] | created_at | timestamp without time zone | updated_at | timestamp without time zone |
ActiveRecordでのアクセス
配列カラムはStringとしてアクセスできます。
>> t = Todo.find(1) => #<Todo id: 1, due: "2008-12-12", task: "Test1", opts: "{1,10,100}", created_at: "2008-12-12 05:21:26", updated_at: "2008-12-12 05:21:26"> >> t.opts => "{1,10,100}" >> t.opts.class => String >> t.opts = "{2,20,200}" => "{2,20,200}" >> t.save => true >> t = Todo.find(1) => #<Todo id: 1, due: "2008-12-12", task: "Test1", opts: "{2,20,200}", created_at: "2008-12-12 05:21:26", updated_at: "2008-12-12 05:32:45">
配列として扱えるようにする
てきとうなコードを書いてみました。
class Todo < ActiveRecord::Base def opts v = read_attribute(:opts) v ? v.sub(/\{(.*)\}/,'\1').split(',').map{|e| e.to_i} : nil end def opts=(v) write_attribute :opts, v ? '{' + v.join(',') + '}' : nil end end
% script/console >> t = Todo.find(1) => #<Todo id: 1, due: "2008-12-12", task: "Test1", opts: "{1,2,3,4}", created_at: "2008-12-12 05:21:26", updated_at: "2008-12-12 05:43:18"> >> t.opts => [1, 2, 3, 4] >> t.opts=[10,100,1000] => [10, 100, 1000] >> t.save => true >> t = Todo.find(1) => #<Todo id: 1, due: "2008-12-12", task: "Test1", opts: "{10,100,1000}", created_at: "2008-12-12 05:21:26", updated_at: "2008-12-12 06:16:05"> >